<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/rss.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Musings</title><description>Mostly shower thoughts and the occasional longer post about programming, technology, and other things I find interesting.</description><link>https://hallobitte.com</link><item><title>The Times They Are a-Changin&apos;</title><link>https://hallobitte.com/posts/2026-03-12_times-are-a-changing</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-12_times-are-a-changing</guid><description>My first post on this blog.</description><pubDate>Thu, 12 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It is early March 2026.
The war between the USA and Iran is still &quot;fresh&quot;.
Everyone is affected by explosions, by which I mean the explosions of prices at the gas stations.
The German government releases the national oil reserves and contemplates stronger regulation on the petrol multi-nationals.&lt;/p&gt;
&lt;p&gt;I was at the bakery.
This bakery is located inside the same building as my soon-to-be-ex employer&apos;s office.
So it was convenient for me to fetch my breakfast from there this morning.
Surprisingly, I became witness of a situation that seemed as mundane as it was out of the ordinary.
The entrance is right on a street corner, and there is no obstacles on the sidewalk in front of it.
As I approached from around the corner I noticed a car placed on said corner.
It was &lt;em&gt;parking&lt;/em&gt; as defined in § 12 Abs. 2 StVO as there was nobody at the steering wheel.
Yet, the engine was running.
Also, the window of the SUV-class vehicle was open and radio music was audible on the street, albeit at an acceptable volume.&lt;/p&gt;
&lt;p&gt;I was mostly taken by surprise by how surprised I was.
This was a cliché on every level - everything about it should be expected.
Maybe the environment was unusual.
The office/bakery building is located in a slightly posh business &amp;amp; living area.
In German, one would describe it as &quot;links-grün versifft&quot; (green-left-wing-filthy) yet gentrified.
There is of course nothing bad to be said about the driver of this car.
As I recall it, it was of German make and model.
And literally &lt;em&gt;everybody&lt;/em&gt; knows that pulling the key for just a brief stop is bad for your Diesel engine.
Still I can&apos;t shed the feeling somehow that this event felt like it has fallen out time.
I for one am happy that electric cars are making the tough choice between engine longevity and burning gas for no reason a thing of the past.
Go ahead - park your 3 ton EV on the sidewalk any time you want.&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>Toss Everything At Me</title><link>https://hallobitte.com/posts/2026-03-13_team-naming</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-13_team-naming</guid><description>Check if your team is doomed with this one simple heuristic.</description><pubDate>Fri, 13 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I think it is generally true that teams in companies are named after the thing they are expected to deliver.
Ideally, that is simply a product name.
If this is the case, the goal definition is pretty much clear:
The team delivers and maintains said product.
As long as the product has users, chances are that it is not being discontinued.
Success metrics are clear and measurable and will include e.g. user retention, user adoption, user satisfaction etc.
The team succeeds if users are happy, which translates pretty much directly into it being able to keep its backlog at a constant size.&lt;/p&gt;
&lt;p&gt;There can also be teams named after whole product areas.
It feels like things get a bit more fuzzy here.
But overall I would argue that it&apos;s mostly about making the decision which products to include in the catalog for the area.
After allocating resources appropriately things should in theory be comparable in lifestyle to the team named after the product.
At the end of the day, it should be clear what falls inside or outside any given area, and areas in a company should have no overlap.
Context switching will be a thing for the team members, though, with larger distances between the topics being the norm.
For this reason, I would be somewhat skeptical of such a team setup, as it inherently signals a lack of focus.&lt;/p&gt;
&lt;p&gt;And then there are the so-called &quot;cross-functional&quot; teams.
Usually, they get named after dimensions of the software engineering process.
In other words, aspects of software that are generally desirable in any software product.
Concrete examples that would come to mind could be &quot;QA&quot;, &quot;Observability&quot;, &quot;Performance&quot;, &quot;Analytics&quot;...
A mistake I have seen people making when they come across a team named after a certain aspect is that they believe they can out-source all the work in that &lt;em&gt;perceived&lt;/em&gt; area to this team.
&quot;We have a performance team, so it&apos;s their responsibility to solve performance in the application &lt;em&gt;I&lt;/em&gt; have built&quot;.
&quot;A user wants to gain some insights in the data they stored in our application? Let the analytics team handle that&quot;.
If you are setting up a team with a name that falls into this category, I implore you to make sure to inform &lt;em&gt;everyone&lt;/em&gt; that the most they can expect from this team to deliver is time-capped, project-level support.
As a simple fix, consider suffixing these team names with &quot;Tooling&quot; to bring it back into &quot;named after a product&quot; land.&lt;/p&gt;
&lt;p&gt;Personally, I will take my own advice here and try from now on to make sure I do not end up in cross-functional teams any more.
FWIW, the German version of &quot;Toss Everything At Me&quot; is &quot;Toll Ein Anderer Macht&apos;s&quot;.
This translates to &quot;Great Another One Doesit&quot;.&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>Instagram Mysogyny</title><link>https://hallobitte.com/posts/2026-03-14_insta-misogyny</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-14_insta-misogyny</guid><description>Me, a guy, mansplaining why it sucks to be a woman on the internet.</description><pubDate>Sat, 14 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I have confirmation that I am not the only person being affected, but let me quickly summarize anyways:
By far the largest reason keeping me from uninstalling Instagram is its chat functionality.
Sure, endlessly scrolling reels is nice and all.
But on the other hand, it is liquifying my brain over time and I&apos;d rather that happened at a slightly lower pace.
Unfortunately, I&apos;m afraid of losing access to Instagram&apos;s chat.
Not because Instagram is a good platform for direct communication in any way.
That couldn&apos;t be any farther from reality.
To be precise, it is the social circle I have built up that&apos;s &lt;em&gt;only&lt;/em&gt; existing within Instagram.
You have to understand, my Instagram handle is a personal identifier with significantly lower sensitivity than my phone number or my email address.
Well, Instagram also wins over email possibly because I&apos;m not 50.
And it&apos;s the same for most people in my generation.
When we meet new people in temporary situations, like let&apos;s say on a vacation or at a festival, our Instagram identities feel like the best option to share.
That&apos;s been my policy for a few years now.
So by now I have a significant amount of contacts I feel at least slightly attached to that I don&apos;t want risking giving them up by deleting Instagram.
I guess this alone is already a cautionary tale.
But it&apos;s not the main topic I wanted to write about here today.&lt;/p&gt;
&lt;p&gt;One thing that I recently witnessed on Instagram with one of my vacation-acquaintances was the following:
Someone had made an account with a handle resembling hers and sent friend-invites to many of her followers, including me.
This impersonation account was suggesting to be my friend&apos;s &quot;secret second OnlyFans promotion account&quot;.
It had a link to the OF account and all (at least I assume the link lead there, I didn&apos;t click it).
&lt;strong&gt;Oof&lt;/strong&gt;.
Another reminder that being a woman on the internet sucks for all my fellow dudes out there.
But it comes worse:
The profile picture was actually her real face with a body standing near a pool, only dressed in a bikini.
I must assume this picture was created using GenAI based on the few publicly available photos of her.
It&apos;s frightening how easy the whole process must have been for the person behind the fake account.
And yet, this could really have been very damaging to my friend&apos;s reputation.
She works as a teacher.&lt;/p&gt;
&lt;p&gt;I must also admit that in retrospect my reaction was probably not what it should have been.
My first thought was not to immediately doubt the validity of this second account.
I think my initial thoughts were more along the lines of &quot;huh, interesting choice - good for her I suppose, making some money on the side&quot;.
Only at the third or fourth thought I started wondering if this wasn&apos;t a bit too risky given her day job.
Then, slowly realizing that this may be an imposter account, I contemplated sending my friend a message.
Something simple like &quot;hey, this you?&quot;.
But I didn&apos;t even do that.
The only real excuse I can give is that I was probably on the loo and cold-DMing her felt like having some friction to it.
Later I saw a story on her real account where she was letting people know that this alt account was not hers.
Only then I sent her a message that I was feeling for her and that I felt sorry this happened to her.
I did not get a message back.
Maybe I shouldn&apos;t have texted.
Or maybe her head was occupied with other things at that particular moment.&lt;/p&gt;
&lt;p&gt;This was not the first time I wasn&apos;t happy with my reaction in hind-sight.
Another (female) vacation acquaintance of mine had her account hacked some months earlier.
For a period of time (2 days or so) her account would suddenly promote some crypto broker or currency or get-rich-quick scheme or whatever.
And here also my first reaction was to roll my eyes about her trying to make some extra money at the expense of others.
I do think all things crypto are a scam.
But it didn&apos;t occur to me that she might have been hacked.
Instead, I unfollowed her account.
I still was friends with the account of her partner which is where I eventually saw the whole story&apos;s explanation.
Now I am too ashamed to send her another follow request again.&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>Willy Nilly</title><link>https://hallobitte.com/posts/2026-03-15_willy-nilly</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-15_willy-nilly</guid><description>The uninvited guest that costs my profession billions of dollars and what Hamlet has to do with it.</description><pubDate>Sun, 15 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Lots of things in software are binary, or at least we have a tendency to make them so.
Sure, the bit, zeros and ones, are underlying any modern computer system.
But rather than that being the root of all things to follow, I think there is yet one more level beneath it.
Too me at least, thinking in binary logic is just the easiest way to think about things in general.
Everyone is thinking in terms of black and white, good or bad, yes and no, ... all the time.
And admittedly, this has gotten us remarkably far at this point!&lt;/p&gt;
&lt;p&gt;Please don&apos;t take this as an excuse to stick to binary-only thinking for everything, however.
I encourage everyone to challenge their convictions from time to time to see if there maybe is nuance to be had.
But let&apos;s not digress.&lt;/p&gt;
&lt;p&gt;Binary systems can represent the the real world out there at every imaginable precision.
Not because they are binary, but because binary is enough to let us approximate anything to the level of detail we desire.
Base-2 is enough to count efficiently, thus to enumerate things.
And once we can assign numbers to (and therefore represent) anything we can think of, the rest we really care for is &lt;a href=&quot;https://en.wikipedia.org/wiki/Decidability_(logic)&quot;&gt;decidability&lt;/a&gt;.
I.e. if a statement about $thing is true or not.
I am not a mathematician, unfortunately, so I cannot academically correctly point out the concrete relationship fot his next statement.
But I think the connection between decidability and set theory must be a fairly short one.
Because what is set theory if not deciding whether $thing is part of $set or not?
To be, or not to be, or something along those lines.&lt;/p&gt;
&lt;p&gt;Code can be correct, or it can be incorrect, i.e. it can fall into either of two sets.
The question about which is which is, unfortunately, undecidable.
But we can use type systems within our programs to partition them efficiently into the &quot;trustworthy&quot; and &quot;not so trustworthy&quot; sets.
Note that trustworthiness is not the same as correctness and not all programs failing to typecheck are automatically incorrect.&lt;/p&gt;
&lt;p&gt;A rather long while ago I came across the blog post &lt;a href=&quot;https://thoughtspile.github.io/2023/01/23/typescript-sets/&quot;&gt;&quot;Making sense of TypeScript using set theory&quot;&lt;/a&gt; by Vladimir Klepov.
While Typescript&apos;s type system has always been intuitive to me, explicitly pointing out the relationship to set theory in this post definitely helped me to get things click into place a bit better.
From this post we learn that, in order to construct members of the set of trusted programs in their host language, type systems make use of set theory as well by exposing programmers to set algebra primitives.
We often don&apos;t notice, though, because of how different the syntax in our programs is from... well, math really.
Also, type system designers have to be generally very careful to find the right balance between ease of use, expressivity, decidability, and generally how well their idea of &quot;trustworthiness&quot; overlaps with &quot;program correctness&quot;.
Designing a type system is not a task to take lightly.
And yet, one absurd decision in type system design has endured for decades, since the mid-60s.
One, that seems incredibly hard to justify if basic logic is applied.
I am talking about a decision that its &lt;a href=&quot;https://en.wikipedia.org/wiki/Tony_Hoare&quot;&gt;original creator&lt;/a&gt; has acknowledged back in 2009 to have been a &quot;billion dollar mistake&quot;.
Most readers will probably know what I am referring to.
But not everybody is following programming language design topics that closely.
And I wanted in this post to also explain (potentially as an exercise to myself) what the mistake is about from first principles so that hopefully most people could follow along.&lt;/p&gt;
&lt;p&gt;A lot of programming tutorials would introduce newcomers to some basic operations on numbers.
They&apos;d show you how the programming language does addition, multiplication, etc.
Then they might introduce variables as a first step to parameterize the computation at hand.
Later they show you how a function is declared, and finally you will have created something akin to the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function sum(a: number, b: number): number {
  return a + b;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great stuff.
A functional function that produces some sums and surely cannot ever be misused.
Because the compiler makes sure nobody is calling it with anything but two numbers, right?
Until some day, someone wakes up and decides to commit this war crime:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sum(undefined, undefined)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compiler will be absolutely fine letting this one slip through (with non-strict settings in the case of TS).
Because, you see, a lot of type systems have decided &lt;a href=&quot;https://en.wikipedia.org/wiki/Willy-nilly_(idiom)&quot;&gt;willy nilly&lt;/a&gt; to add an uninvited guest into the &lt;code&gt;number&lt;/code&gt; type.
The &lt;code&gt;number&lt;/code&gt; type does not just include all numbers.
For whatever reason there is also this weird extra guy called &lt;code&gt;undefined&lt;/code&gt; in there.
Most of the popular languages in software development still do this.
If your first interaction with programming is through one of the following languages, you are confronted with a world where null/nil is just a fact of life and you may never have any reason to question it.
Something like SQL, Java, JavaScript, or even &lt;a href=&quot;https://groups.google.com/g/golang-nuts/c/rvGTZSFU8sY?pli=1&quot;&gt;Go&lt;/a&gt;, a language having received its first stable release in 2012(!).&lt;/p&gt;
&lt;p&gt;Btw, did anybody check what exactly happened in our code example above?
Because the fun didn&apos;t end at the misuse of our innocent little function.
The language runtime designers (who are different people from the type system designers) decided to want to go wild as well and made it so that &lt;code&gt;undefined + undefined&lt;/code&gt; produces a &lt;code&gt;NaN&lt;/code&gt; value.
This value, short for &quot;not a number&quot;, is another value that the type system recognizes to be a valid &lt;code&gt;number&lt;/code&gt;.
Another uninvited guest to our party.
But, in large parts contrary to our previous acquaintance &lt;code&gt;undefined&lt;/code&gt;, Mr. &lt;code&gt;NaN&lt;/code&gt; comes with bad manners, too!
Somebody decided that it is the reasonable thing to make &lt;code&gt;NaN === NaN&lt;/code&gt; evaluate to &lt;code&gt;false&lt;/code&gt;.
Also, &lt;code&gt;0 * NaN&lt;/code&gt; is still &lt;code&gt;NaN&lt;/code&gt;, as is &lt;code&gt;NaN / 0&lt;/code&gt;.
On the other hand, &lt;code&gt;1 / 0&lt;/code&gt; is defined to return &lt;code&gt;Infinity&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What is remarkable here is that even the rust people couldn&apos;t get this right.
Not because they didn&apos;t want to.
The reason why they had to include the &lt;code&gt;NaN&lt;/code&gt;-madness in their language as well for the &lt;code&gt;f32&lt;/code&gt;/&lt;code&gt;f64&lt;/code&gt; types is simply that every processor in the world that is remotely modern and relevant is using the IEEE754 standard for floating-point arithmetic.
And this specification unfortunately makes it so that we have all these ugly &lt;a href=&quot;https://en.wikipedia.org/wiki/IEEE_754#Special_values&quot;&gt;special values&lt;/a&gt; manifested into hardware for all eternity.
So, on this front, I&apos;m afraid to say humanity has lost.&lt;/p&gt;
&lt;p&gt;Just like it has with &lt;code&gt;NULL&lt;/code&gt; in the SQL standard.
To date probably the largest-scale attempt to embed &lt;a href=&quot;https://en.wikipedia.org/wiki/Three-valued_logic&quot;&gt;Three-Valued Logic&lt;/a&gt; into a programming system.
And everyone hates it.
I once proposed a tabular compute language where &lt;code&gt;NULL&lt;/code&gt; would be treated at least so that it is equal to itself, making use of the ugly but useful &lt;code&gt;IS NOT DISTINCT FROM&lt;/code&gt; construct.
But a dear colleague pointed out to me (to great dismay on my end) that postgres cannot create indexes on that, dooming any join to be a slow nested-loop join.
Concrete sources that would prove my claims here on this are sparse.
I could only find this post on &lt;a href=&quot;https://stackoverflow.com/questions/40830940/postgresql-poor-performance-in-left-join-is-not-distinct-from&quot;&gt;StackOverflow&lt;/a&gt;.
I also remember having read the &lt;a href=&quot;https://postgresql.nabble.com/How-to-hint-2-coulms-IS-NOT-DISTINCT-FROM-each-other-td5928175.html&quot;&gt;nabble post linked&lt;/a&gt; from there which since seems to have died and isn&apos;t available on archive.org either.&lt;/p&gt;
&lt;p&gt;What are the alternatives to having special values added to all types, though?
How should we let a caller know when an operation did not produce a (meaningful) value?
The answer is &lt;a href=&quot;https://en.wikipedia.org/wiki/Tagged_union&quot;&gt;sum types&lt;/a&gt;.
In Typescript, with &lt;a href=&quot;https://www.typescriptlang.org/tsconfig/#strictNullChecks&quot;&gt;strict null checks&lt;/a&gt; enabled, the following is a perfect way let callers know about the possibility of absence of a return value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// Will return `undefined` if `n` is not found in `ns`
findIndex(n: number, ns: readonly number[]): number | undefined { /* ... */ }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In rust, we have the &lt;code&gt;Option&lt;/code&gt; type, which can come in the flavors &lt;code&gt;Some(value)&lt;/code&gt; or &lt;code&gt;None&lt;/code&gt;.
C++ gives us &lt;code&gt;std::expected&lt;/code&gt;.&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>IRrigation</title><link>https://hallobitte.com/posts/2026-03-16_irrigation</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-16_irrigation</guid><description>A short post about DRY.</description><pubDate>Mon, 16 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As software developers, we often find ourselves in the situation that we want to convince our peers that something about some code we like should stay or something we dislike should go out or be done differently.
In order to do so, we need to come up with &lt;em&gt;arguments&lt;/em&gt;.
Unfortunately, personal taste isn&apos;t a good argument, and someone&apos;s experience seldomly means anything to anyone but the person who made it.
So we try to come up with arguments that appear to be objective and, even more importantly, which sound &lt;em&gt;smart&lt;/em&gt;.
Academia gives us the perfect toolkit to draw from here.
And so we use phrases like &quot;Hollywood principle&quot;, &quot;Separation of Concerns&quot;, &quot;SOLID&quot;, &quot;KISS&quot; to try to intimidate the other side and feel good about ourselves.
One more element in that list is the mantra of &quot;Don&apos;t Repeat Yourself&quot;, or just DRY in short.
And yes, trying to compartmentalize common sections of code so that they can be reused, remixed and composed well is a very important part of our jobs.
If every time we wanted to make an apple pie we had to build up the universe from scratch we&apos;d never get anywhere.&lt;/p&gt;
&lt;p&gt;Unfortunately, in practice I have found DRY to be overused by people, however.
I am definitely not the &lt;a href=&quot;https://news.ycombinator.com/item?id=40525064&quot;&gt;only&lt;/a&gt; &lt;a href=&quot;https://news.ycombinator.com/item?id=32010699&quot;&gt;one&lt;/a&gt; to have noticed that, so I&apos;ll not expand on this a lot here.
Maybe just a small stinger:
Most of the time where I found DRY to be cited in a situation where I didn&apos;t disagree the underlying problem was that the respective colleagues just didn&apos;t have good taste / intuition about well-composing components.&lt;/p&gt;
&lt;p&gt;What I really wanted for this post to be about is a somewhat interesting realization I had while being WET (i.e. in the shower).
In my previous experiences I have found that when it comes to intermediate representations (IRs) of some data to be processed there isn&apos;t really a ceiling as to when it becomes &lt;em&gt;too many&lt;/em&gt; intermediate representations.
Fundamentally, this seems to be in direct violation of the DRY principle.
And yet, compiler developers - the subgroup of practitioners in our profession we revere the most - cannot get enough intermediate representations in their compilers.
Parse tree, abstract syntax tree, mid-level IR, low-level IR, target-lowered IR, assembly - these are all intermediate representations any compiled program code will go through until finally there is an executable binary produced.&lt;/p&gt;
&lt;p&gt;It should be clear that each representation is just there to be the best data structure for a certain stage of the compilation process to operate on.
Practice has shown that splitting up the process into these stages has made the overall complexity of compilation manageable.
But each time, a decision had to be made to introduce yet another way to represent a program in memory on top of the N different ways that had already existed before.
There would have been quite the reluctance to do so as it is anything but DRY.&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>Feels Good</title><link>https://hallobitte.com/posts/2026-03-17_feels-good</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-17_feels-good</guid><description>The world is on fire, but this blog feels lit.</description><pubDate>Tue, 17 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I only have this blog for a couple of days now.
Yet, overall I am &lt;em&gt;very&lt;/em&gt; pleased with it so far.
One aspect to it is of course this feeling of doing something worthwhile and also getting better at it with each new post.
I.e. linearizing thoughts into a coherent argument, doing compelling story-telling etc.
All that in my second language, with no help by any LLMs (at least so far).
Yes, some of my writing is clunky, some points don&apos;t come across as clearly as I want them to, yada yada.
What really counts is me having the discipline to stick to it.
And after all, nobody forces me to keep the &quot;one post per day&quot; rhythm.
If I&apos;d switch to a bi-weekly or even weekly cadence that&apos;d be just fine as well.
Actually, I have the feeling that for some of the people I want to read this blog the posting frequency might already be a bit too high.&lt;/p&gt;
&lt;p&gt;The other half of what makes this experience so pleasant for me, however - and I don&apos;t mean this in a too self-absorbed way - is just how nice I find it to open up this blog&apos;s webpage in a browser.
I only really realized it today.
Of course, the theme choice I still feel comfortable with (although I should maybe consider adding a dark mode).
And on top there are so many additional things which make this website feel great in my opinion.
And by &quot;are&quot;, what I really mean is: there aren&apos;t.
No loading times - the page is there instantly.
No cookie banners to click through.
And best of all, no attention-grabbing flashy ads that stick out like a sore thumb design-wise.&lt;/p&gt;
&lt;p&gt;I went into the browser console to check what&apos;s being loaded.
And even though there is 200ms passing until the website is fully loaded, making 53 network requests overall and 645,75 kB / 163,98 kB being transferred over the network (I assume that&apos;s deflated vs. gzipped) it&apos;s just so much better than what I&apos;m used to on the internet these days.
It&apos;s really a shame what we collectively put up with.
Things could be better for all of us.&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>Parking Lot Life (Pt. 1)</title><link>https://hallobitte.com/posts/2026-03-19_living-on-a-parking-lot</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-19_living-on-a-parking-lot</guid><description>Reflecting on when I was living the van-life dream and how I got into it in the first place.</description><pubDate>Thu, 19 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I started my working career in April of 2019.
I had just finished my master&apos;s degree, thought the world was my oyster, and had very leftist political opinions.
In hindsight I must say that I was unbelievably lucky to have graduated at this particular point in time.
While I can&apos;t recall the overall economic situation, at least in software the job market was great.
Originally I had plans to go abroad for my first job as I didn&apos;t have the chance (or if I had I missed them all) to spend time abroad during my studies.
However, I wanted to go to an English-speaking country which didn&apos;t just leave the EU and was close to home in case something would be happening to my grandparents.
So basically I had narrowed down my options to Ireland.
In addition to that, I wanted to find a job in compiler engineering.
So even given the circumstances, it proved a bit hard to even find one position that matched these requirements.
Time passed, and eventually even the 5 months I had given myself to transition from student life to working life were coming to an end.
Long story short, at some point I dropped all my demands and just wanted to find something close to where I already lived, as long as it was at least in my favorite programming language of the time, C++.
That turned out to be much easier, and after a short while I found myself being accepted at a huge corporation for an entry level position.
The only catch was that this company had its offices in hicksville, 35 minutes train ride from the city I lived in.
The audacity!
Wasting almost 2 hours of my valuable lifetime each day just to get me to my day job was unacceptable.
Buying a car - also unacceptable.
I would not sell out on my values of a green lifestyle like that.
So should I move to this small forsaken town?
Absolutely inconceivable.
None of my friends would live there.
And given the size of the company I worked for it wouldn&apos;t even be cheap as all my colleagues were competing for flats.
Since I could live in my student dorm for a couple more month before the were going to kick me out I had some time still.
But I had to come up with a plan.
And so slowly an idea was forming within me.
&quot;Society is pampering car owners in this country so much anyways&quot; I thought.
Prime real estate given out for free everywhere just for people to place there private steel enclosures on for 90% of the day.
Maybe I &lt;em&gt;was&lt;/em&gt; stupid not to take advantage of this.
As the newbie, I was placed in a 4-person office room together with my manager.
One day I asked him if he thought it possible for me to just live in a van on one of my employer&apos;s many parking lot.
He thought I was joking and found the whole idea very funny.
But he didn&apos;t say no, or rather he said something like &quot;don&apos;t see why not&quot;.
That sure as hell was enough for me.
It sounded genius on paper:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&apos;d have zero commute&lt;/li&gt;
&lt;li&gt;Instead of paying rent I&apos;d pay down on owning my van&lt;/li&gt;
&lt;li&gt;I&apos;d be free to go wherever on the weekends&lt;/li&gt;
&lt;li&gt;I could use my employer&apos;s bathrooms for all sanitary demands for free&lt;/li&gt;
&lt;li&gt;If need be, a gym-chain membership would also give me access to showers and bathrooms in different cities in the region&lt;/li&gt;
&lt;li&gt;Washing I could do at friends/family/laundromats&lt;/li&gt;
&lt;li&gt;I would trim down significantly on personal belongings, basically to just the essentials&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Almost too perfect.
People around me of course could come up with &lt;em&gt;some&lt;/em&gt; aspects of my envisioned lifestyle that might be inconvenient.
There were, however, no arguments that seemed grave enough to me to deter me from pursuing this plan.
And so I put down a 20k€ down payment on a 57k€, 1 year old Volkswagen California Coast in July 2019.
An enormous amount of money, very much absurd to be honest.
The reasoning behind me going with such a fancy car, however, were these:
The Volkswagen / Dieselgate scandal was still very much present in everyone&apos;s mind at the time.
I didn&apos;t feel like living in a &quot;historic&quot; 30 year old+ car to be freed from any legal requirements.
Yet I also didn&apos;t want to find myself excluded from driving into certain areas because my car was causing too much air pollution.
So in my mind I &lt;em&gt;had&lt;/em&gt; to go with a fairly recent model.
I also wanted my van to be inconspicuous and not too impractical for everyday usage.
Entering parking garages would ideally still be possible.
So the California-series delivery-van base paired with a fold-out roof seemed like the best option to me.
I can&apos;t tell exactly any more why I didn&apos;t look at other manufacturers&apos; offerings.
I believe the Ford Nugget-based version didn&apos;t seem to allow sleeping in the main cabin but only on the fold-out roof level.
Maybe I also didn&apos;t trust brands like Opel or Fiat very much.
I can&apos;t really tell any more.&lt;/p&gt;
&lt;p&gt;And so, after having picked up my new home on a Friday afternoon, one hot Sunday evening in the mid of July, I finally found myself spending the first night on my employer&apos;s parking lot.
This adventure ended up lasting 7 months.
There were many lessons I had to learn and overall I think it was a very formative experience.
But to go into more detail on it I shall be doing another time, in a second part of this blog post.&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>On Health Insurance</title><link>https://hallobitte.com/posts/2026-03-20_on-health-insurance</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-20_on-health-insurance</guid><description>Revealing my position on the economic political compass.</description><pubDate>Fri, 20 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This morning I had my regular dentist appointment.
It didn&apos;t turn up anything noteworthy.
I don&apos;t floss well, so there was a bit to do for the dental technician to get my teeth cleaned nice and well.
Maybe I&apos;ll improve my floss routine for the next few weeks a bit again just to gradually have my motivation for it fizzle out afterwards.
On the bright side, I don&apos;t have cavities.
Overall, my dentist always expresses satisfaction with my overall dental health.
I do have what he calls &quot;abrasions&quot;, though.
That&apos;s because I clench my jaws while I&apos;m asleep - probably also when I&apos;m not asleep.
But at night is just the most convenient time to put in a dental splint as I have a habit of not eating or talking during that time.
The check-up appointments with my dentist usually also serve for letting them have a look at the state of my bite-guard.
This led to a slightly awkward situation for me as I had to tell my doctor I had decided to move to some generic product from the internet over the custom-made appliances he had hooked me up with the previous years.
You see, in 2025 I bit through a total of 3 separate splints.
There is a point to be made just about the sheer amount of plastics I swallowed because of this circumstance.
But the real reason behind me looking for alternatives was the price point.
On Amazon, I can get a pair of bite guards for 20€.
That&apos;s 10€ each.
And those aren&apos;t even the cheapest option.
I just went with them because they somehow seemed a bit more trust-worthy than the others.
Generally speaking, however, I don&apos;t have high standards.
It&apos;s fine for me that they are bulky - I can get used to that.
To be honest, at the rate I bit through the professionally-made models my doctor anyways went with thicker and thicker models.
They are also more rubbery, so I think there might be fewer parts coming off that I will swallow at night.
Amazon also has fully custom-made ones for less than 100€ on offer for anyone that is skeptical of the generic thermo-plastic ones.
Now compare that to what the dental guards I got from my dentist cost me:
Each one came in at around 450€, putting me at roughly 1350€ for one year.
That is 45 times the amount I now pay for the one from Amazon.
And so far, they seem to have similar durability.
It&apos;s still 4.5x the amount of custom-made &quot;free market&quot; offerings.
It just didn&apos;t seem cost-effective to me to pay this much money for something that might as well just be a piece of wood to keep my jaws separated.&lt;/p&gt;
&lt;p&gt;At crossfit I have a buddy who works as a dental lab technician.
When I told him about my struggles and that I would go with a dental guard from the internet he was surprised.
&quot;If it&apos;s paid by the insurance anyways why even worry about the price?&quot; he asked me.
I pointed out that I get to pay the money out of pocket (at least initially).
But even if that wasn&apos;t the case, the money would need to come from somewhere.
Insurance companies don&apos;t print Euro bills in their basements to my knowledge.
For a while now, there has been an ongoing discussion in German media outlets that our health system is too expensive.
Well, German health insurers are complaining frequently and premiums go up every so often that it&apos;s hard to lose track of the topic.
Let me quickly outline the situation as it presents itself to regular citizens like me.
At the core of the German health system is the division between public health insurance and private health insurance.
Employees must have health insurance, so most of us Germans come into contact with the system.
There is multiple options on either side of the public/private divide that can vary in what services are covered under insurance and other bonus programs.
However, you are only free to choose to go into private health insurance if your yearly income exceeds 77,400€ (as of 2026).
The most noticeable differences in everyday life between the two forms are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Doctors are more happy to take you when you have private health insurance because the can ask (AFAIU) up to 2.3x the price for the same service as they can bill publicly insured patients.&lt;/li&gt;
&lt;li&gt;For publicly insured patients, doctors are interacting directly with the insurance company to get compensated. If you are a private patient, on the other hand, the first recipient of the doctor&apos;s invoice is you and it&apos;s also you wiring the money to the doctor, not the health insurance.
You will ask your insurance to reimburse the money to you.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Point one indicates there is a pricing catalog for each form of therapy doctors can prescribe and enact to their patients
Everyone doctor only can ask a certain amount of money for a procedure because every insurance is only going to pay exactly what is written in that catalog.
And yes, this system is absolutely causing certain procedures to be &lt;a href=&quot;https://de.wikipedia.org/wiki/Fallpauschale_und_Sonderentgelt&quot;&gt;over-prescribed&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;From point number two you can already derive which category of insurance I am in.
While it is more inconvenient, I do think being able to see the invoice and having to act on it is a good thing.
It influences personal behavior and reduces the risk for mistakes or even fraudulent invoices.
On the other hand, private health insurers also need to validate incoming reimbursement requests, potentially leading to more effort and costs on their end.
I hear that the newly rolled-out German electronic health record service also has a feature to access the invoice information.
It may be doubted, though, whether without any active involvement in the invoice settlement process people will look closely at what doctors are billing their insurance.&lt;/p&gt;
&lt;p&gt;But aside from a more or less believable spend control aspect, why &lt;em&gt;is&lt;/em&gt; the German health insurance space designed the way it is?
I didn&apos;t research this really, but the availability of different companies to choose from indicates to me that the idea is to somewhat bring market dynamics and competition into the space.
As was brought up earlier already, with everything being priced according to a centrally defined catalog, this is kind of a tough goal to achieve.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Personally, I was never with an insurance that my parents hadn&apos;t already picked for me, though.
Maybe that is just due to my own laziness, however.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, from what I understand, once you cross a certain income threshold, the government starts trusting you enough that you can graduate from a fully-imaginary toy market to a slightly-less-imaginary toy market when it comes to choosing your health insurance company.
I will freely admit that, politically speaking, I am an opponent of egregious over-spending.
I also believe in the concept of distributing life&apos;s inherent risks across all members of society fairly.
Phrased differently, nobody should die of a curable illness because they are lacking the money for medication.
But in between, there is a wide spectrum of cases that are not as easily categorized into one of the two extreme ends &quot;preventable death&quot; vs. &quot;unnecessary over-spending&quot;.
To bring these two points into balance, sure, why not try with a market model to rationalize spending if possible?
E.g. Prophylaxis is an area that also makes an extreme amount of sense - invest small earlier to prevent high costs later.
Economics is telling us clearly that overspending on prevention on the individual level statistically amortizes across the whole population.
Unfortunately, applying statistics quickly gets us back into unethical territory.
It hasn&apos;t been too long ago that women in private health insurance had higher premiums than men just because of their gender.
Only in 2013 the European supreme court ruled that health insurances always have to follow an &lt;a href=&quot;https://de.wikipedia.org/wiki/Unisex-Tarif&quot;&gt;&quot;Unisex Tarif&quot;&lt;/a&gt; model.
So, apparently health insurance companies are in most cases restricted from performing risk analysis on their customers.
Unlike with banks, I don&apos;t think there is much money to be saved in service costs if the company restricts itself to only customers that know how to use the internet.
I may want to research this, though.&lt;/p&gt;
&lt;p&gt;Speaking of things I want, I don&apos;t know where I want to go with this.
I don&apos;t think there really is a market, nor do I think there should be a market for how we handle individual health matters.
What I believe to be true is that it will always be the case that more money buys you more.
In a world where all the patients that are now in private health insurance were to be merged back into public insurance it is still very conceivable to see private extra insurances becoming the norm to have access to better treatment.
Sure, one could try to forbid this by law.
Then only the very rich who can afford private doctors (and maybe people with connections or unafraid of bribery) will have preferential treatment.
But I can&apos;t even tell you if I think &lt;em&gt;that&lt;/em&gt; is an improvement over what we have currently.&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>Postal Voting</title><link>https://hallobitte.com/posts/2026-03-22_postal-voting</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-22_postal-voting</guid><description>Some things in life seem to good to be true and make me nervous. What am I overlooking?</description><pubDate>Sun, 22 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Voting by mail has taken my heart by storm in 2021.
Germany was about to decide the successor of Angela Merkel after 16 years of CDU.
&quot;Fridays for Future&quot; was still very popular.
The smell of change lay in the air for everyone to notice.
However, it was clear that the effects of the COVID-19 pandemic would still cause complications to this national election.
At least for me, it was out of the question to show up in person at a polling location.
Those should remain reserved for the old and vulnerable that didn&apos;t know how to cast their vote in other ways.
So for the first time in my life, I registered for voting by mail.
During the few elections I had been allowed to take part in before I believe I thought it more cost-effective for society to throw off my ballot in person.
This time, the circumstances just didn&apos;t allow it, though.
I don&apos;t really remember the details of the registration process any more.
But it must have been pleasant enough to completely turn me over as to this date I have never voted in person ever again.
Nowadays, when I get the election notification, there&apos;s already a QR code printed on the letter.
Scanning it leads me to a page where I fill out a couple of input fields and 3 days later I have all the required documents to vote by mail.&lt;/p&gt;
&lt;p&gt;In 2021 this led me to have been done with the election weeks in advance and causing me to actually be surprised when election day finally came.
Since that date didn&apos;t have any significance for me any more I felt free to plan a trip around that time.
And so it happened that I was actually in Berlin on that particular Sunday.
Me and my companions took part in the last Fridays for Future demo in Berlin.
If memory still serves me right it was one of the biggest ones.
On our way back to our accommodations we even met a famous politician of the Green party doing campaigning.
I was completely star-struck which was slightly awkward.
However, she was very nice and gave me pin wheel that I keep in one of my flower pots to this day.
&lt;img src=&quot;./windrad.jpg&quot; alt=&quot;Pin wheel promoting the German Green Party&quot; title=&quot;Renate Künast herself assembled this one for me&quot; /&gt;
On the Sunday itself we actually wanted to leave Berlin which proved to become quite difficult.
Some geniuses hat planned the Berlin marathon to fall onto election day and most roads leading out of the city were closed.
This was so troublesome, in fact, that in some locations voters were unable to vote because ballots couldn&apos;t be brought in on time and some of the affected areas&apos; elections had to be repeated later.
As a mail-voter, this of course affected me in no way whatsoever.
It sometimes surprises me to learn that so many people still vote &quot;the old way&quot;.
While the overall share of mailed ballots still rises (ignoring out the COVID outlier) with each election according to the &lt;a href=&quot;https://www.bundeswahlleiterin.de/service/glossar/b/briefwahl.html&quot;&gt;German election administrator&lt;/a&gt;, it&apos;s still almost two out of three voters voting at the station.
I do see the appeal of getting to see the local elementary school from within and not having to trust the postal system.
Maybe I also don&apos;t want to miss out on &lt;em&gt;all&lt;/em&gt; the dirt that gets dug up until the very last day of campaigning.
But are these the only advantages?
Because on the other hand I see&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;having the clear conscience of already having performed my civil duties weeks in advance&lt;/li&gt;
&lt;li&gt;not having to be anywhere specific on that particular Sunday&lt;/li&gt;
&lt;li&gt;not having to wait in line&lt;/li&gt;
&lt;li&gt;having all the time in the world to fill out the ballot at home, rather than blocking a cabin&lt;/li&gt;
&lt;li&gt;if you die between sending in your ballot and election day, it still counts!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These arguments in my view more than make up for the downsides.
Am I missing something?&lt;/p&gt;
&lt;p&gt;This is a bit like the recurring discussion about nuclear energy.
I just have no idea how anyone can still justify even throwing the idea of new nuclear power plants out there.
Do I live in a bubble where all the cited draw-backs are just imaginary?
If you have credible answers to any of these two points, please feel invited to reach out!&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>VPS YAGNI</title><link>https://hallobitte.com/posts/2026-03-23_yagni-vps</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-23_yagni-vps</guid><description>How I narrowly escaped from cloud-native microservices on Kubernetes clusters with serverless functions intertwined with sprawling CI/CD pipelines</description><pubDate>Mon, 23 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The technical setup behind this blog is is incredibly effective in my opinion.
When I want to add a new post, all I need to do is to log into my Github account, create a new markdown file in a certain directory of my &lt;code&gt;blog&lt;/code&gt; repository and commit it to &lt;code&gt;main&lt;/code&gt;.
Apparently, I could do this from the Github app on my phone - although I didn&apos;t test it as it didn&apos;t seem obvious to me if this is committing the file right away.
&lt;img src=&quot;./create.jpg&quot; alt=&quot;Github app on iOS showing a &amp;quot;create file&amp;quot; option&quot; title=&quot;Github on iOS lets me add new files no problem&quot; /&gt;
Editing is also possible, albeit probably not the greatest experience in practice.
I would prefer having a preview mode before publishing a post.
However, if on the go, this is a viable option.
&lt;img src=&quot;./edit.jpg&quot; alt=&quot;Github app on iOS editing a file&quot; title=&quot;Editing a markdown file on iOS - not pleasant, but workable.&quot; /&gt;
Once a new commit hits the &lt;code&gt;main&lt;/code&gt; branch, some simple Github actions workflow is run to have the static site generator (Astro) do its thing and deploy the result on Github pages.
I don&apos;t even have to worry about the SSL certificate for the webpage, as Github is taking this over for me as well.
Did I mention yet that my blog has a commenting feature that is using Github discussions in the background?
That is powered by the excellent &lt;a href=&quot;https://giscus.app&quot;&gt;Giscus.app&lt;/a&gt;.
I don&apos;t have to worry about the server side of hosting this blog one bit - everything is being taken care of by Github.
And the craziest of all things is:
It&apos;s absolutely free.&lt;/p&gt;
&lt;p&gt;Yes, this won&apos;t come as news to my technically versed readers.
But I wanted to contrast this to what I was considering to do before landing on this solution.
I don&apos;t think I would have if it wasn&apos;t for a very dear colleague of mine.
I&apos;ve been paying &lt;a href=&quot;https://www.netcup.com/en/&quot;&gt;my hosting provider&lt;/a&gt; for a &lt;em&gt;very&lt;/em&gt; long time now for two different services:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The domain &lt;a href=&quot;hallobitte.com&quot;&gt;hallobitte.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A Virtual Private Server (VPS) that I shared with a friend from university&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So when earlier this month I decided to start blogging, my instinct was to make use of &lt;em&gt;both&lt;/em&gt;.
The only issue was:
I absolutely dreaded getting familiar with the state of my v-server again.
Back when we set this up, I was a nerdy student with lots of time.
So of course I went with the same Linux distribution I used on my laptops and desktops: Arch.
Because nobody got time to go through a major version upgrade every one or two years, am I right?
Unfortunately, I made a couple of mistakes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Early on, I installed Gitlab on this VPS.
Not in docker like a sane person.
But using AUR build scripts instead.
This basically taught me that software updates needed to be supervised, because something about this setup would break almost every single time I did an update.&lt;/li&gt;
&lt;li&gt;So I never set up automatic updates.
AND I didn&apos;t really like doing them regularly.
So of course I fell behind &quot;quickly&quot;.
Right now, this VPS has an uptime of more than 1500 days(!!!).
People using Arch Linux likely know that, at this point, one just &lt;em&gt;cannot&lt;/em&gt; update any more to latest packages.
Doing a full reinstall is the most time-effective solution here.&lt;/li&gt;
&lt;li&gt;Unfortunately, as I am sharing the VPS with a friend, I can&apos;t just wipe everything and start from scratch.
My choice of Arch Linux always meant &lt;em&gt;I&lt;/em&gt; would be doing the base system administration as he mostly works with Debian/Ubuntu servers professionally and otherwise stays in Windows where possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Something had to be done to get out of this whole mess and towards something better™.
But what would that be?
Well, ideally a Debian base, of course.
And the other thing I wanted was &lt;em&gt;visibility&lt;/em&gt; for our individual &lt;em&gt;deployments&lt;/em&gt; and entailing configuration changes for &lt;em&gt;shared resources&lt;/em&gt;.
Put more simply, I wanted to have a &lt;em&gt;web ui&lt;/em&gt; to configure what had been nginx config file changes and systemd units in our existing server.
Because at the end of the day, all we want to do is have some things in auto-start that get properly exposed exposed on the internet, either multiplexed via http or via port mappings.
I asked an LLM if there was a solution for this and it told me to have a closer look at &lt;a href=&quot;https://coolify.io/&quot;&gt;coolify&lt;/a&gt;.
While I found it a bit off-putting to see that this was written in php, I guess it would have fit the bill?
But then I&apos;d have needed to solve getting my blog&apos;s markdown files into docker containers first I suppose.
Possibly not the low-friction entry I was hoping for.
I did take the opportunity, though, to dig a bit into the technical terms I wasn&apos;t intimately familiar with that I kept seeing floating around in the docs.
For example, one thing I realized is that what we nowadays deploy as containers behind traefic used to be just processes behind fast-cgi.
Communication has just shifted from local sockets to http and of course we have better isolation and possibly scaling options.
But in my VPS use case, it&apos;s pretty much that.
I think the effect that understanding this had on me wasn&apos;t much other than just feeling old.
Oh well.&lt;/p&gt;
&lt;p&gt;Today, I shared my blog with another colleague at work.
You should &lt;a href=&quot;https://adam.sr/&quot;&gt;check him out&lt;/a&gt;.
One thing he was reminded of reading my earlier post &lt;a href=&quot;../2026-03-17_Feels-Good.md&quot;&gt;Feels Good&lt;/a&gt; was &lt;a href=&quot;https://jsomers.net/blog/speed-matters&quot;&gt;this old but great post&lt;/a&gt; by James Somers.
It made me think whether I&apos;d ever had gotten to &lt;em&gt;anything&lt;/em&gt; resembling a blog with posts if I had pursued my impractical initial ideas.
I am grateful it has turned out the way it has.
I want to say a big Thank You to Benni for pointing out to me that I didn&apos;t need any of the VPS shenanigans I outlined above - I couldn&apos;t be happier with the setup I have now.&lt;/p&gt;
&lt;p&gt;While I&apos;m at it, I also want to thank &lt;a href=&quot;https://stelclementine.com/&quot;&gt;Stel Clementine&lt;/a&gt; for sharing her blog&apos;s template open source.
We don&apos;t know each other.
But your work was the second biggest factor to get this blog off the ground to my satisfaction in an incredible small amount of time.&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>Intercompany Feelings</title><link>https://hallobitte.com/posts/2026-03-26_intercompany-feelings</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-26_intercompany-feelings</guid><description>Evaluating my current mental state.</description><pubDate>Thu, 26 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This post&apos;s title is misleading and that is exactly why I chose it.
This is not going to have anything to do with anthropomorphized enterprises getting into bed with each other (although that does sound like a lot of fun as well).
But rather, this post is about &lt;em&gt;my&lt;/em&gt; feelings at this moment where I&apos;m in between jobs.
It would be disingenuous to this blog, my readers - most of whom are (ex-) colleagues -, and to myself not to address my recent departure from my previous employer in some form.&lt;/p&gt;
&lt;p&gt;I&apos;ve been with this company for three years and eight months.
A lot of things happen during such an amount of time and it has definitely left some marks on me.
I learned a lot, be it about technology, myself, or office politics.
I also had the pleasure to meet a whole lot of cool and interesting people from different backgrounds and cultures.
Finally, I also leave behind the things I have been continuously working on for several years.
Things I created, maintained, and helped shape.
There are definitely many aspects I am going to miss.
On the other hand, I have to admit that it is immensely freeing to be in the position to cut some ties.
Just having the option to switch to something new, back in that moment I felt a sense of &lt;em&gt;agency&lt;/em&gt; I can hardly describe.&lt;/p&gt;
&lt;p&gt;Interestingly, three-and-a-half&apos;ish years is also about the same time span I worked in the first job I had after uni, the one right before this one.
A somewhat obvious question to arise here is therefore whether I should worry about an emerging pattern.
Frankly, in both instances I have actively been starting to look for new positions.
That means in each case the underlying reason can be clearly attributed to &lt;em&gt;some sort of dissatisfaction&lt;/em&gt;.
Am I growing dissatisfied after 3.5 years, is that it?
I find it somewhat hard to imagine that anything I don&apos;t actively put my focus on would go on over a time horizon this large.
Then again, I have no clue how emotional account keeping works.&lt;/p&gt;
&lt;p&gt;What I do know, however, is that not all factors of dissatisfaction are created equal.
I would say the reasons behind me leaving my first job vs. my second one were quite different overall.
If I wanted to phrase it poignantly, maybe I would say that in the first job I saw &lt;em&gt;too much&lt;/em&gt; perspective whereas in the second I eventually saw &lt;em&gt;too little&lt;/em&gt;.
I.e. in the first job I was given the impression I could do anything, anywhere.
I was the rock star junior dev in my team, and that might have gone to my head.
&quot;So why would I keep doing it here?&quot; my younger, over-privileged me thought.
Now, with the job I just left, I rather ended up &lt;em&gt;not&lt;/em&gt; seeing any more potential for where I could go next to grow.
That&apos;s why, in my head, I &lt;em&gt;had&lt;/em&gt; to try to find my luck elsewhere.
And by the way, that is still what I am out for!
Finding luck, i.e. a place where I can feel happy at for a long time.&lt;/p&gt;
&lt;p&gt;I do not find the process of changing jobs enjoyable at all.
It&apos;s probably also not getting better any time soon in the current economic and global political climate &lt;em&gt;and&lt;/em&gt; AI coming after all of us.
And I think I have to consider myself very lucky landing my next job with the amount of effort and time investment I spent.
Without checking the details, I believe what it took was roughly 2-3 months, sending out somewhere in the ballpark of 15 or so applications.
I only got into the interview stage with two of the companies I applied to, though, one of which made me the offer I ended up  accepting.
Not a slam dunk, and far from a pleasant experience.
The amounts of time I innocently pulled up my phone randomly to look at god-knows-what, seeing an email notification and then getting hit by a rejection mail out of the blue were just brutal.
But I was also still far from hundreds of monthly applications with no response at all as I sometimes hear about.&lt;/p&gt;
&lt;p&gt;Leaving my previous safe haven by resigning from my job was taking on a risk.
New probation period, new and unfamiliar working environment, new routines to adapt to because of a different commute.
But I am hopeful it will pay out.
I get to see what others have been working on and get to learn new ways of doing things.
On the other side, I will try to bring in my skills as best I can to prove myself and pull more than my own weight.
I will meet new colleagues which will show me their unique perspectives and I hope to be able to contribute some of mine.
And I will have new pathways open up to me which will shape my way going forward.
It is quite exciting if I&apos;m being honest.&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>We Have Visitors</title><link>https://hallobitte.com/posts/2026-03-30_we-have-visitors</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-03-30_we-have-visitors</guid><description>My view on what the visitor pattern is about and why I think it&apos;s often misunderstood.</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In my third semester at university it was compulsory to participate in a practical course on software engineering.
For that we were assigned into groups of five and given the whole semester to work on one of several different software projects.
My group got the task to develop an app that should teach the basics of &lt;a href=&quot;https://en.wikipedia.org/wiki/Lambda_calculus&quot;&gt;lambda calculus&lt;/a&gt; to children by portraying abstractions as alligators and variables as their eggs.
This idea was based on a &lt;a href=&quot;https://worrydream.com/AlligatorEggs/&quot;&gt;post&lt;/a&gt; by &lt;a href=&quot;https://en.wikipedia.org/wiki/Bret_Victor&quot;&gt;Bret Victor&lt;/a&gt;.
While it was a bit quirky, the app we created came out quite nicely and satisfied our advisors to the degree that we were asked to &lt;a href=&quot;https://www.youtube.com/watch?v=pb1G23i5mBU&quot;&gt;present it&lt;/a&gt; during an open house event of our university.
It&apos;s still possible to find all the code we wrote during and after the project on &lt;a href=&quot;https://teamcroggle.github.io/&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As part of the implementation process, we had regular check-ins with our advisors where they would give us some guidance on how to structure the coding process and the code itself.
One of the lessons from that time included the tip to use the &lt;a href=&quot;https://en.wikipedia.org/wiki/Visitor_pattern&quot;&gt;visitor pattern&lt;/a&gt;.
That was where first I learned to appreciate this pattern and to this day I think it addresses a very important issue in software engineering in a clever and arguably elegant way.
However, I encountered some ... &lt;em&gt;disagreements&lt;/em&gt; on what this pattern is and isn&apos;t in my professional career since then which has somewhat dampened my enthusiasm for it.
I have also found that it can be &quot;dumbed down&quot; a bit in practice to make it more obvious what&apos;s going on.
But before I elaborate on this, let&apos;s first take a step back and quickly reiterate the problem the pattern is intended to solve.&lt;/p&gt;
&lt;p&gt;:::note
This is of course &lt;em&gt;my&lt;/em&gt; understanding of the pattern.
I think in all instances where people were of different opinion they were arguing that there was &lt;em&gt;more&lt;/em&gt; to it than what I believe it should boil down to.
I will address these &quot;omissions&quot; later in my post and why I think it does not make sense to entangle them with the core of the visitor pattern.
:::&lt;/p&gt;
&lt;p&gt;Wikipedia says the following about the visitor pattern:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A visitor pattern is a software design pattern that separates the algorithm from the object structure. Because of this separation, new operations can be added to existing object structures without modifying the structures.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think, speaking abstractly, this is actually a very good and concise description of the pattern.
However, maybe we can be a bit more concrete by going through a practical example.
Let&apos;s assume we are modelling an &lt;em&gt;animal shelter&lt;/em&gt;.
There are a couple of things we need to be able to do with the animals that are brought to our attention.
For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;house&lt;/code&gt; animals depending on their needs, i.e. putting them in an aquarium if they are fish etc.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;feed&lt;/code&gt; them&lt;/li&gt;
&lt;li&gt;&lt;code&gt;healthCheck&lt;/code&gt; them&lt;/li&gt;
&lt;li&gt;give them &lt;code&gt;specialCare&lt;/code&gt; in regular intervals&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This list will grow for sure once we actually get into business.
But we have to start somewhere.
The intuitive first solution might be to make all these operations available as &lt;em&gt;methods&lt;/em&gt; on the &lt;code&gt;Animal&lt;/code&gt; interface that all animals have to inherit from.
Unfortunately, this causes a couple of problems.
First off, we don&apos;t &lt;em&gt;own&lt;/em&gt; all the implementations of animals in the world - nature does.
So we can&apos;t just enforce all animals to implement our custom interface.
Secondly, it will cause quite some noise in the animals&apos; implementations to implement all our operations and a lot of churn every time we need to modify or extend the operations we need to have available to run our animal shelter.
What we need, and Wikipedia already said it, is to &quot;[separate] the algorithm from the object structure&quot;.&lt;/p&gt;
&lt;p&gt;But next we run into a different problem:
We of course want to continuously make sure that every operation we are regularly going to need is supporting all the different animals that our shelter supports.
Ideally, once a new animal is brought to us that we haven&apos;t seen before &lt;em&gt;something&lt;/em&gt; should make sure we cannot forget adding support for it in all the necessary places.
As for all things that we want to be ensured in our code, that &lt;em&gt;something&lt;/em&gt; that checks it should be the compiler.
So we need a way to let our operation coding signal to the compiler which animals it supports so that it can figure out when there is something missing.
Now &lt;em&gt;this&lt;/em&gt; is the place where - in the classic visitor pattern - an interface comes into play.
For each animal variant there is going to be a &lt;code&gt;visit&lt;/code&gt; function in the interface that communicates &quot;I, the operation, know how to visit (i.e how to &lt;em&gt;deal with&lt;/em&gt;) &lt;em&gt;this&lt;/em&gt; particular animal&quot;.&lt;/p&gt;
&lt;p&gt;In code, this could look somewhat like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Cat {}
class Dog {}
class Fish {}

interface Visitor {
  visitCat(cat: Cat);
  visitDog(dog: Dog);
  visitFish(fish: Fish);
}

class HouseAnimal implements Visitor {
  visitCat(cat: Cat) { return &apos;cardboard box&apos; }
  visitDog(dog: Dog) { return &apos;kennel&apos; }
  visitFish(fish: Fish) { return &apos;aquarium&apos; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now there is just one final piece missing.
Namely, how to bring arbitrary animal instances together with their respective method implementation in the visitor-based operations.
The solution to this is called &lt;a href=&quot;https://en.wikipedia.org/wiki/Double_dispatch&quot;&gt;&quot;double dispatch&quot;&lt;/a&gt;.
Quoting from Wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;double dispatch is [...] a mechanism that dispatches a function call to different concrete functions depending on the runtime types of two objects involved in the call&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In our case, these two objects are 1. the animal instance and 2. the operation instance.
The second one we of course get for free in most languages - calling the &lt;code&gt;visitCat&lt;/code&gt; function of a &lt;code&gt;HouseAnimal&lt;/code&gt; instance is trivial as long as we know the operation we want to use is indeed &lt;code&gt;HouseAnimal&lt;/code&gt;.
And even if we didn&apos;t know which &lt;code&gt;Visitor&lt;/code&gt; implementation we have at hand, most modern programming languages conveniently hide the dynamic dispatch in the background for use.
Dispatching based on the animal instance is the harder part.
Back in university, we were taught that using &lt;code&gt;instanceof&lt;/code&gt; is super bad.
Honestly, if you keep your inheritance hierarchies flat (as you should) I don&apos;t see a big issue with it, though.
So our first option would simply be something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Animal = Cat | Dog | Fish
function dispatch(animal: Animal, visitor: Visitor) {
  if (animal instanceof Cat) {
    return visitor.visitCat(animal)
  } else if (animal instanceof Dog) {
    return visitor.visitDog(animal)
  } else if (animal instanceof Fish) {
    return visitor.visitFish(animal)
  } else {
    throw new Error(`Unhandled animal: ${JSON.stringify(animal satisfies never)}`);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IMO, this is perfectly fine as long as we have the &lt;code&gt;satisfies never&lt;/code&gt; guard in place there, making sure we handle all kinds of incoming &lt;code&gt;Animal&lt;/code&gt;s.&lt;/p&gt;
&lt;p&gt;If we allow ourselves a bit more extra information on the &quot;object structure&quot;, we can also go e.g. with type tagging:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Cat { readonly type = &apos;cat&apos; as const }
class Dog { readonly type = &apos;dog&apos; as const }
class Fish { readonly type = &apos;fish&apos; as const }
type Animal = Cat | Dog | Fish
function dispatch(animal: Animal, visitor: Visitor) {
  const { type } = animal
  switch (type) {
    case &apos;cat&apos;: return visitor.visitCat(animal);
    case &apos;dog&apos;: return visitor.visitDog(animal);
    case &apos;fish&apos;: return visitor.visitFish(animal);
    default: {
      throw new Error(`Unhandled animal: ${type satisfies never}`);
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://www.typescriptlang.org/play/?#code/MYGwhgzhAEDCYBdoG9oCcCmYAmB7AdiAJ7QJEAOG0AvNAOTCJ3STTAERIC+AUKJDAAiuAOYp0WPIRJlKNenhHNW7fJ2i9+UaADEAlhAAW4zDgLFSFKrToAzA4eUxV63rKoBBfHoC2YEPLwSAA+0MJiofpGPLYArvjACHoE0NgG5IjAhgAUYN5+IABc0F6+-gA00ABuBnoIuGjFAGq19WgAlCg80GwcSKjuGvJ5ZSDd0BAA7nVZ0NnuncjjPYwQVAxMxZgIsWj41a0NAHQ1EHVBufn+7QDcy2yQ64p0Wxg7ewdnbSet4Zejt3uq3W9iMLwk732pzqx2hCCiORGBUBPR62AwtjAsRACGKS1RqIQhjQuEm0HwGDJAFE0CS0NkAAYAVXwhjy2BAGGwLCuRWgABJkIMIIgDPYMDAKVUMGguAyUajeD1eFwgA&quot;&gt;TS Playground&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If we have even more influence on the definition of our object structure, we might even want to do what we got taught in university:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Cat {
  accept(visitor: Visitor) {
    return visitor.visitCat(this)
  }
}
class Dog {
  accept(visitor: Visitor) {
    return visitor.visitDog(this)
  }
}
class Fish {
  accept(visitor: Visitor) {
    return visitor.visitFish(this)
  }
}
type Animal = Cat | Dog | Fish
function dispatch(animal: Animal, visitor: Visitor) {
  return animal.accept(visitor)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://www.typescriptlang.org/play/?#code/MYGwhgzhAEDCYBdoG9oChrTMYBTADggBQBuAlhGQgPYBOAXNAGoVV0CUK6mmtuCAV1oA7aOUo1aAOnFV4xBAAsKnDNAC+aTaEgwAItQDmXNdjyFSrSYxYSOJntD6CRYq3RlWDhokpXcNLTQdKGgAMQpFBywcAmJZa2Z3Wk5UNV5+IVEEjwSIiEVfZQhVTE1NBABPfFxoAEFhMgBbMBBoAF44RGgAH2hvXvDItAAzAWFgBDJqUQATCnxEYEKwRpaQRgbm1oAaNzsGJIPUtWcsrDXWqTM4y2OtIA&quot;&gt;TS Playground&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However, I don&apos;t like this too much for a couple of reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;There is a relatively meaningless extra function on the public interface of every animal&lt;/li&gt;
&lt;li&gt;The object structure now needs to know about the &lt;code&gt;Visitor&lt;/code&gt; interface&lt;/li&gt;
&lt;li&gt;The dynamic dispatches in both &lt;code&gt;animal.accept&lt;/code&gt; and &lt;code&gt;visitor.visitXYZ&lt;/code&gt; do quite some heavy lifting.
This can be confusing to readers. Furthermore, they aren&apos;t &quot;free&quot; if you care deeply about performance&lt;/li&gt;
&lt;li&gt;Dynamic dispatch does not work well with generics.
While not shown in the code examples above and not really an issue in Typescript, generally it is desirable to be able to choose the return type of an operation freely.
In languages where generic code gets &lt;em&gt;instantiated&lt;/em&gt; on each type parameter assignment it is generally not possible to also have it be the target of a dynamic dispatch.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Especially point number 4 makes it really hard to recommend this approach.
Personally, I&apos;d rather go with the type tagging approach instead.
Check out this code on &lt;a href=&quot;https://www.typescriptlang.org/play/?#code/MYGwhgzhAEDCYBdoG9oCcCmYAmB7AdiAJ7QJEAOG0AvNAOTCJ3STTAERIC+AUKJDAAiuAOYp0WPIRJlKNenhHNW7fJ2i9+UaADEAlhAAW4zDgLFSFKrToAzA4eUxV63j1lUAgvj0BbMCDy8EgAPtDCYmH6Rjx6+AgYaLZgwFQAagZ6CLhoADwASgB8KDzQ0ABumQjBABSMCABccIgAlE35ANylFVURNYpNEW3Qnd2VEFnRhjX2Rk1Tw6NutgCu+MAIegTQ2AbkiMCGBYU1YD7+IE3efgEAND0T2WhNGY85xy0lZS5IqB4a8jONxA3QgAHcsodoDUPJ9kN1vpAqAwmE1MAgVmh8A8sjkAHTjLK1IEXFpdMqIiDIxR0NEYDFYnFPAm9USnc4BMkIthI+izRx0hnYwnMkVTdnArkUnYYZIrECNL7S0iGNC4MHQfAYDUAUTQarQNQABgBVfCGM7YEAYbAsDmXaAAEmQ-wgiAM9gwMC15USXCNUopvDKvDcWhgAAlcCsqdcLtA-ORrb4MPEYK9cXlOGg4iJivCyiLavUmsFhtncyZ6ZjsSi0NgAEa4MD16BNgAezGDTL6A3ConLCBz+DEqHRNfoAGtU1qQF2xlVxfz5g5B8PRxIhfQwABHFYtvQrXzzsPgbQ6DA2uMBBO+JMYFNp6AZp65cq4PTYfMLx7FxCl1omnfT8UG7EVe1EQYByAj9bWQMDFwcGYHBXIxhmAuDQx4PgOFwa08RANldggfYEEOGotQ1PoWnuSjoCjGMMGvEAahaNiOiAA&quot;&gt;TS Playground&lt;/a&gt; for a full-fledged example.&lt;/p&gt;
&lt;p&gt;So this was a quick run-down of what &lt;em&gt;I&lt;/em&gt; believe the visitor pattern is largely about.
Where might others have different opinions on this?&lt;/p&gt;
&lt;p&gt;The first argument I could think of here is how much &lt;em&gt;centralized knowledge&lt;/em&gt; there needs to be regarding the shape of the object structure.
I have seen people argue that it should be possible to completely do without listing all the animals in a single place.
I.e. in my code examples, the following should ideally disappear:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Animal = Cat | Dog | Fish
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, maybe the visitor interface could be rewritten to more simply state that it can deal with all kinds of animals.
So something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// This is now a base class
class Animal {}

interface Visitor {
  visit(animal: Animal)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I will admit, if you move the goal posts far enough, something like this can work for varying definitions of &quot;work&quot;.
Of course, initially it seems a bit absurd to assume some operation can work generically over any kind of animal it has zero knowledge of.
And that is kind of the contract we have been given here, right?
All that an implementation of &lt;code&gt;Visitor&lt;/code&gt; may assume on its argument is that it subclasses the &lt;code&gt;Animal&lt;/code&gt; base class.
But what if we never wanted to handle all possible incoming variants of animal but just the ones &lt;em&gt;we&lt;/em&gt; explicitly know and care about?
Of course that is then a totally different problem from the one we started with (being an animal shelter for all animals brought to us, accommodating our code if needed for any newcomers).
Then basically what we want is to null-route or reject all the things we don&apos;t want/care.
That is fine - but I wouldn&apos;t call it a use case for the visitor pattern any more.
Luckily, I&apos;ve only come across this opinion once in my career.&lt;/p&gt;
&lt;p&gt;The second understanding of the visitor pattern which diverges from the one I laid out above has been much more prevalent, however.
I&apos;ve seen this three or four times across different code bases now minimum.
I attribute it coming from the general setting the visitor pattern is usually employed in.
And that setting is &lt;em&gt;graph or tree data structures&lt;/em&gt;.
In the app we programmed, our domain object structure with alligators and eggs really was a model of a syntax &lt;em&gt;tree&lt;/em&gt; of lambda calculus.
And whatever operations I wanted to perform, I usually didn&apos;t just want it to be performed on individual nodes in that tree but rather the whole syntax tree.
So in addition to acting on node types, I needed to traverse the tree and keep track of inter-node relationships.
And there is where I think a mistake is easy to happen:
Conflating tree traversal with node-type-based dispatch (the thing the visitor pattern solves).
&lt;a href=&quot;https://en.wikipedia.org/wiki/Tree_traversal&quot;&gt;Wikipedia&lt;/a&gt; list 3 * 2 = six different ways to traverse (binary!) trees.
To me, that is a big hint to try to encapsulate the complexity inherent to this somewhere separately.
In other words, if your visitor ends up having dedicated &lt;code&gt;visitBeforeChildren&lt;/code&gt;, &lt;code&gt;visitBetweenChildren&lt;/code&gt;, and &lt;code&gt;visitAfterChildren&lt;/code&gt; callbacks, I think you are doing it wrong.
I do understand that sometimes it needs to be possible to inspect the current traversal state in order to make the decision.
And if this works for you who am I to tell you to do it differently?
I just find that &lt;em&gt;knowing&lt;/em&gt; that you have &lt;em&gt;tree traversal&lt;/em&gt; and &lt;em&gt;type-based dispatch&lt;/em&gt; as two distinct problems on your hand may lead to code that is structured more clearly and thus better to reason about.&lt;/p&gt;
&lt;p&gt;FWIW, I coded up a slightly more complex application of the visitor pattern including a tree and state-tracking depth-first traversal in &lt;a href=&quot;https://www.typescriptlang.org/play/?target=9#code/PTAEFpM0HkCMBWBTAxgF1AZzQJwK7p45IRTgBQaAngA4kDCAhhgLygDeo1dAXKAOQpm-UAF9KtEgBEA9gHNQbTtyR9+AE3kjxK0ADEAlpgAWijl0lqAZkePaJdUAEEAdgYC2jADZmmGAD6gsgqBhibkDiROAI54jDgGeO5mypYCjLHxie78ANygNiZ8YcYA2gC6YpGgTDjqcDLx6gBCMgAeKRa8AkJ1DU3gDW15oEJofH5VugDSSC4uSD5KXaoCANZzC14jmnKYfMEVU5KgABKMcAZozGYxcQlJoIG19Y11rR2Bs-OLEboASjIZMllio1DggTl8sYLldmPszrDrmgjjoTgBlYyLNBIHCdMECEzY3EjCHAhGA4Go6quDzeAAyMjGBhkLjMmOJeMClOSgXOl2RT2cbk8XgiIFIUFAADUjFcZHiaMwcTg2ZgkGg8DRJZByAYXCqrIwUCRZZh5TgADz-AB8HHIoFAADc5Wg-AAKMYTZgASj4-wdztdwXduwO8j9oADjpd5rQJXdhWMxVskejQbjdyySXdGXu2T4WYe7jTgdjVxe-Xe7XdQ29fTeLXapZjru+W3dGx+Xj47cWLYzVx57rJ7n9kIH5bQHK8KvdRNnuL4M5VpfE5CseBc6BZbPURiVaBQxmtNtzPeFdK8jOZrIANIO0Aq+GaLaeffbHShWdhzLpRGY3iBpgADuVzHqA7oqB+7CBl+jDqj0wh8MQmqqo+CoAHRTh63g+nBowISQGhaChGpEGyU5YVOIZ4QRQiIfwSb8GRaGUa61GugmdGOvBjF5tmOSsRRGE4NhrpFtk574bxhGMb0rwDEMLGgKhIlUWJOFNFWTZtNJ9FEesmyLCpanoRp4lxn2Xj6bJDHEaOpnkeZHGaa6w48bx9mElii44E5bGiZZVwrritm8eoSBGngs58LBsmOmgxgQiBoALKlACiOAQjg7oAAYAKouDCLjqF4SDqKAjAit4fAACTsLomDMEYNhIJgaVIE6uKiHlMm8eIjriOuEpkOAzheHICpXMYY5BEgNBJeAhg4L+6JIPEEFgUloAbTgXhUOASBtFcoAeDQ5XuHMOKVQhok6hQuhSFYmDosiJDLIeyaXqKN4tay1JPS96IGHILjeJ0FwKmgAD8fANDI5XVccjjPZgTBeF4cDGmsZjzu9BzA+9H4sHaaMg2DQHfi4v4wNMKTiNTv4uEC2psO6JN2nT5AoF4CEdVIejomd7gXUgV0Gh1r5Pla5Og+DXh2vFoA0AkTrMCQxCMJoLgHVgBNBETGudF9fDUoGqsGOrOKjD+uAEDL7qW9bmsbTresoHAhPo94WM4zB66OtgLUoFwOCMN1q1IOehY1deTL-S4D6e97GN+ygawwQR+6YIex7ng+6VBELnpwD6-WByravG9txgxz9DIJ2gu4PpgeBwBCeDNwsfAc4oZPA-LeHexTCufrxSVGJhwc4phX1z3gJjhV+duqe1ZiT5gmGe1BxhTzPSD9Y6BhWJBxBb1DOBoFnCVcHvW8H3PzDGHPMg0BzBGOmZbLnwRg1eavNuHd15sCAZ3bu0cfS5AIpvae70n5JVfu-I+a9ApgPaphS+sMsDt3PqAMimBAyVy0mgT0zBvTX3Hl-ZybJYG1zIWgQurMK5lmDPIUM8hwxyBvrxb+d8p70N2Ewt+LDWxxgTEmFMJgeHUMCnQmaiZbDCJoKIx8kkcwCWLIWTIxZIxy0pj4ZWsiRLyKSrmHR2QHx91JlQ3iVgFSQSZhgJMoAZCn00dkTCSYZEJScWvDqbAc55zrkmB8m8UGyRPmfDBWCfG3z4b-W+Q1P5VHiTQ2A0w-6qK0g2JoHxaztHrIpasbQ9GDwMbYvhpi65DCsZzUAQTmD5yGNvZgYT77lyIawqyxkbJdi2L2XpZTXpD0MQRKp99ML0P6YsOp-dbGOnsXiT0q9diuNPjMrwmFdiYDiQAmmGA8GBIPE0uuQj+G7JScfU+I4YkNCvns2SCT2pXNSQlf+Tz0nc1kqIbJ7lIQjkhOOYEwzR4QyMagkxkz6GjjmTYiFiyHErIOaAGEAobhuNUpCTCaK4RoF2Qs-Zv4jkNJOUeOuuLkTtKMBE3iUTbkX3uZQhFCVnmEKSW8n5KS+HfIGn8uMoVcoLhVMuXyq4R6jMqek6p84xW4jhUrFJSzHGr1HOsrAcqxKjgJSyleKKSWNPJYC4E1LLkcvpefTBTLHm8PSYkpJHyBrcq+Zkn5LCRpgDGqAAqzU5AkExYLYWtcw4R1xM1HwB8zo0zoDuVkD0NxbljWyGwpUAAKz9ZWclFZyB8tUG7x1vC4SMtJfpN13EcQIW5IopoquPcqGBTb5r+s3AGlRK2lSivqWtbAq2doWOoQMgbMK4FDVHTNfkrHsEbTQX58zOAEXpTQTBpDwAAEYfQAEJFAsDYHhcwKSvpmFKJhE9NByj5GdYFTgWC+D2xIABP+u0vCIRZXw9gjr-6-MDHwr65APUPVAAAFXahgJKJBvyRXjTzQBmrs1+RSIGAk-BhUkjvN+yECJSgERZUhxyaHb6UvhGbV5uqJ5pH4B4pI-B8McoKLYYjtHeKkdvkh5iryuWMfKK80QNHb7MZWGoBSOlBjtGo+xwi4xCUsfI2Mfg4nHUcYSlxxTXH1x+LGHjFDWqMOlAAAzlBxUieEpRV2VDupWRsHwfStLQNBlFYx007TYCm9Qjm65aeTr6OzmBEZIEwl4dhJ6bNuY3ZhTw78IY2O8MOyQ5cgA&quot;&gt;this playground example&lt;/a&gt;.
I hope you could find this helpful.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item><item><title>Visiting The Hague</title><link>https://hallobitte.com/posts/2026-04-09_visiting-the-hague</link><guid isPermaLink="true">https://hallobitte.com/posts/2026-04-09_visiting-the-hague</guid><description>Reflecting on this year&apos;s Easter weekend trip.</description><pubDate>Thu, 09 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It is starting to become a tradition for me and my significant other to do a nice little trip over the Easter holidays.
My girlfriend is more into nature than cities, which sounds like it might narrow down the list of possible destinations but really doesn&apos;t.
Turns out living in the center of Europe makes it possible to reach a wide variety of places and landscapes within reasonable time.
One year ago, we went to &lt;a href=&quot;https://en.wikipedia.org/wiki/Saxon_Switzerland&quot;&gt;Saxon Switzerland&lt;/a&gt;, the area around Dresden in eastern Germany.
Given that this was a more mountainous region, this time we set our eyes on reaching the sea.
And, because ever since I visited Rotterdam a couple of years ago I became a fan of the Dutch coastal region, we eventually settled on visiting The Hague in the Netherlands this year.&lt;/p&gt;
&lt;p&gt;Neither my girlfriend nor I own a car.
But from experience I also knew that taking a train would be taking long, would be cumbersome, and would limit our flexibility when there.
That&apos;s why we chose to rent a car from the car sharing service we both are subscribed to.
In particular, we opted to take a VW ID.3 pro.
I had driven the Cupra Born the also have on offer in the past before and both cars share the same technical foundation.
So I didn&apos;t expect there to be much of a difference.
In hindsight, I can&apos;t tell if it was just because of familiarity, but I&apos;d say maybe the VW felt a bit &quot;nicer&quot; on the road.&lt;/p&gt;
&lt;p&gt;Overall, we were traveling from 10:30 to roughly 18:00 on Friday to get from Karlsruhe to our hotel.
However, this included a short stop at my place in Heidelberg and two or three charging stops, one of which we combined with having lunch.
We opted to book a somewhat more fancy Hotel (at least for our standards) which was located right at the beach.
It even came with a sauna and infinity pool in the top floor.
Additionally, we booked the breakfast buffet for all of the 3 days of our stay.
The car we left in a close by garage which we paid for upfront.
That was around 80€ for the 72 hour tariff.
After check-in and settling into our room it was already getting dark outside.
So we only did a small stroll along the beach.
It was also extremely windy.
This can even be seen on the cover foto of this post!&lt;/p&gt;
&lt;p&gt;The next day, Saturday, we got up somewhat early and decided to take the tram into the city.
Similar to other cities like e.g. London you don&apos;t need to worry about getting a ticket prior to boarding.
One can just tap in and out with the credit card using dedicated terminals near the doors.
Once we arrived in the city center, we found ourselves near a small market.
One of the stalls there was offering freshly hand-made &lt;a href=&quot;https://en.wikipedia.org/wiki/Stroopwafel&quot;&gt;Stroopwafels&lt;/a&gt; which we had to try.
These were quite amazing!
&lt;img src=&quot;./stroopwafel.jpg&quot; alt=&quot;Me and a two-legged brown flower enjoying Stroopwafels&quot; title=&quot;Stroopwafels freshly prepared in a waffle iron, manually cut in half, and having caramel sauce spread on it sure is different from the store-bought options.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;After exploring the city center a bit more my girlfriend booked us a boat tour over the &lt;a href=&quot;https://en.wikipedia.org/wiki/Gracht&quot;&gt;Grachten&lt;/a&gt;.
This was, unsurprisingly, an excellent idea.
We had a delightful tour guide telling us all kinds of facts about the city and its buildings while we were cruising over the water.
Gracht bridges don&apos;t have much clearance so we regularly had to duck in order to not bump our heads against one of them.
&lt;img src=&quot;./boattour.jpg&quot; alt=&quot;The Hague&apos;s skyline as seen from a boat&quot; title=&quot;We were extremely lucky with the weather as well. The bridge seen here is an exception in how high it rises over the canal.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;By the time the boat tour had completed it was already close to 4pm.
Some of the smaller museums we were thinking of visiting were already closing by that time.
We still wanted to try our luck at the &lt;a href=&quot;https://en.wikipedia.org/wiki/Mauritshuis&quot;&gt;Mauritshuis&lt;/a&gt;, however.
While the length of the waiting line ended up a bit off-putting, I did see a former colleague standing in it.
What a coincidence!
Unfortunately he didn&apos;t see me, but I texted him and we could verify that it really was him.&lt;/p&gt;
&lt;p&gt;After having decided that Sunday was going to be our museum day we decided to head back to Scheveningen, the quarter of The Hague at the coast where our hotel was located.
There we went top the area around the &lt;a href=&quot;https://en.wikipedia.org/wiki/Kurhaus_of_Scheveningen&quot;&gt;Kurhaus&lt;/a&gt;, the &quot;seaside resort&quot;.
My girlfriend had some &lt;a href=&quot;https://en.wikipedia.org/wiki/Kibbeling&quot;&gt;Kibbeling&lt;/a&gt; for dinner while I was having some fries.
Afterwards, we also walked down the pier and ended up hopping onto the ferris wheel.
&lt;img src=&quot;./ziplining.jpg&quot; alt=&quot;People zip-lining from the pier towards the beach&quot; title=&quot;While we opted for something more relaxed, others were doing more extreme activities like zip-lining or even bungee-jumping.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Finally, we made our way back to the hotel after a long walk on the beach where we checked out the spa amenities on the top floor.
A beautiful sunset topped off this very much perfect day.&lt;/p&gt;
&lt;p&gt;Sunday we again got up rather early for our taste.
After another extensive breakfast, we made our way back into the city, noticing that the city was still rather unpopulated.
Our first stop was the Mauritshuis which we had already been &lt;em&gt;close&lt;/em&gt; to visiting the day before.
It&apos;s an old building with a modernized basement turned into a reception hall and three stories filled with 300 year old paintings.
While initially I admired the skill with which these artworks had been painted, I grew number the higher up we got during the tour.
This was very unfortunate as we only got to see the most famous paintings at the very end.
On the bright side, my girlfriend bought me a new pair of socks in the museum merch shop depicting &lt;a href=&quot;https://en.wikipedia.org/wiki/The_Anatomy_Lesson_of_Dr._Nicolaes_Tulp&quot;&gt;&quot;The Anatomy Lesson of Dr. Nicolaes Tulp&quot;&lt;/a&gt; by Rembrandt.
&lt;img src=&quot;./mauritshuis.jpg&quot; alt=&quot;The most famous painting inside Mauritshuis somewhere in the background&quot; title=&quot;An impromptu line was forming in front of the Girl with a Pearl Earring for people to take photos. The museum attendants had to disband it while being quite annoyed.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Once we were done with the old paintings we continued our way to the &lt;a href=&quot;https://en.wikipedia.org/wiki/M._C._Escher&quot;&gt;Escher&lt;/a&gt; museum to get to see some less-old paintings.
I really admire his work, both aesthetically as well as from how complex it is.
His works were also extended by some information about the palace the museum is housed in.
Overall, the size and scope of this museum better matched my limited span of attention.
&lt;img src=&quot;./escher.jpg&quot; alt=&quot;Me standing in an optical illusion chamber next to a seemingly much smaller cute blue flower&quot; title=&quot;Thanks to the other visitor taking this picture of us when the stationary camera was broken. Unfortunately I was too awkward to also think of a cool pose.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately I started feeling quite ill roughly at the beginning of our visit to the Escher museum.
While the symptoms receded after a while (or rather I heroically pushed through them) I was a bit spooked and we decided to cut the day shorter than we initially had intended.
We still grabbed a small lunch in the city and got some groceries for later but decided to head back soon afterwards.
Dutch people not giving a damn about Sunday or Easter and still opening their shops be praised!
Luckily, the weather was great and we could have yet another nice walk on the beach before I ended up laying in bed for the rest of the day.&lt;/p&gt;
&lt;p&gt;Finally, on Monday, we had to get back home.
But of course not after having one last big breakfast from the buffet and spending &lt;em&gt;just a little&lt;/em&gt; extra time near the beach.
&lt;img src=&quot;./shoreline.jpg&quot; alt=&quot;Watching down the shoreline from one of the jetties near our hotel&quot; title=&quot;We were having immense fun watching the locals do all the different kinds of water sports - surfing, wind surfing, kite surfing, and even some crazy people bathing at freezing temperatures.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;What I have left now after an absolutely amazing weekend is some wonderful memories and a cute fridge magnet in the shape of a bicycle - and some small souvenirs from the famous coffee shops they have over there ;)&lt;/p&gt;
</content:encoded><author>Lukas Böhm</author></item></channel></rss>