s e m i s t a b l e . c o m



11.10.2019: Languages...
This makes me wonder: when we are discussing languages and their perceived complexity, should we perhaps take the associated libraries and the size of the ecosystem into account as well? And a fun fact you can't see on the picture: the React book is tiny bit wider, but not quite as deep! ;)

20.08.2019: The Surprising Sanity of Using a Cache but Not Updating It
A while ago we added some client side caching to a biggish application at work, as you do. This led to an interesting observation I would like to share:

We clever monkeys realised that we have a handful of different call arcs that go through this cache, and that not all of them are similar in terms of functionality. For example some of them can handle the inconsistencies introduced by the cache, other cannot and were therefore modified to bypass the cache. So we end up with different code paths that return pretty much the same data, "just" one cached and one not. Urgh, not very nice. But probably the price one has to pay for having this cool cache that will make everything blazingly fast, right?

We dutifully monitored everything, including cache hit rates. And we did see really high hit rates, as expected for this cache, and the expected cache warming patterns when the system boots up. How nice when things go as expected!

Except that now and then something weird happens: it looks almost as if the cache randomly goes back into a mostly-cold state and then goes through the warming pattern again! How can that be? Unfortunately I don't have a quality screenshot from our monitoring system (too much noise to be usable here), but the following graph shows the same behaviour from a Monte-Carlo simulation built to experiment with this behaviour:

The simulation takes a simple LRU cache with a maximum size of 1000 entries. Access is following a Poisson distribution with 50% of all hits going into the first 300 cache entries, and a total of 10000 things that could be cached. The simulation makes 100 calls per time unit, and is run 100 times to get averages and deviation. The simulation code can be found at
https://github.com/robertlemmen/cache-weirdness/blob/master/cache-sim1 You can clearly see the cache starting cold with a low hit rate, then warming up and reaching something resembling steady-state around 30 of whatever that time-unit is. All matching what one would expect.

Halfway through the run the cache is hit with a different access pattern, a linear scan through all items. In our system this was a housekeeping task, not so uncommon to have. This linear scan of course (in hindsight) destroys the LRU property of the cache, now the entries are pretty much random ones (funny how sequential and random can sometimes be the same thing), rather than the ones most likely to be used again soon. And with this, the return to a 10% cold state suddenly and sadly makes perfect sense!

In our case we ended up still using the cache, but in this call arc we do not update it when there is a cache miss, a capability I promptly added to my perl6-cache-async library (https://github.com/robertlemmen/perl6-cache-async). But I guess the benefits of using the cache for this access type are not that great and just bypassing the cache entirely would have been fine as well.

More interesting than the code-level fixes are the design consequences though: Having different code paths for access to the same data, just with different correctness guarantees, seems unfortunate but perhaps acceptable. But different code paths for access patterns that return the exact same data with the same guarantees, but with a different probability what will be called next? That seems insane! This entirely destroys the idea of domain driven design and pushing technicalities like caching into a transparent infrastructure layer. Even worse: the code we added the cache to is a service, the client making the calls with that access pattern is somewhere else. So we need to expose this nastiness in the API and can't hide it under the carpet. And us adding the cache required changes to that client code, exposing unexpected far coupling.

So, caches: making your design shitty in unexpected ways!

24.04.2018: A less Stern Look of Disapproval
A while ago a great person called Karen wrote a Perl 5 Module called Acme::LookOfDisapproval (
cpan). It allows you to use a well known and visually clear character sequence instead of the somewhat cryptic Perl "warn" method:
    ಠ_ಠ 'cannot handle request due to missing foobricator';
While this module probably has not found it's way into too many production systems, I want to argue that it is a very useful module line-for-line: For a start it has exposed a couple of bugs and weirdnesses in all sorts of systems that handle Perl 5 modules. But more importantly it raises interesting questions about how a language can allow and support modification and extension of "core" features that are deeply entangled with concepts like exception handling. And it teaches a great many things about how Perl 5 really works. So it is only natural that this module must be re-implemented in Perl 6 to see if similarily interesting effects turn up! The good, or boring, news is that the implementation is quite straight forward and pretty much free of magic:
    sub ಠ_ಠ(*@message) is hidden-from-backtrace is export {
        warn @message;
So there you are. One interesting bit is the "hidden-from-backtrace". As it turns out this is a trait modifier, and while this looks like some special case in the language (the "is export" even more so), it is pretty much free of magic. Interestingly it is not an annotation like some Java folks would expect, and it is not through reflection in the traditional sense that this is used when printing the backtrace. Instead the trait actually modifies the routine that it was invoked on. Perhaps the following, also highly useful, example illustrates this point:
    multi sub trait_mod:<is>(Routine:D $r, :$broken!) {
        $r.wrap({ warn "broken sub $($r.name.perl)!!!"; callsame; });
    sub holler() is broken {
        say "woohoo";
And while this sort of aspect-oriented programming needs to be used with some restraint, it is a great example of how Perl 6 manages to build generic and simple yet powerful mechanisms into the core language, and then leverages them at higher levels to implement language features (like the backtrace or export management) without the usage of any voodoo or special cases. A similar topic to look at would be how the underlying exception behind "warn" manages to resume at the point it was thrown (call/cc anyone?), but one thing at a time.

22.03.2018: confluence vs google docs
recently a colleague recommended, honest and with good intentions, that we could improve the way we work by collaborating on documents in google docs while they still undergo a lot of change, and then copy them into confluence for safekeeping once they have stabilised. took some time for that to settle! makes me wonder if the state of the world makes mr cunningham laugh out loud or roll up in a ball and cry...

22.02.2015: downtime is the new uptime
after the ancient device was excavated from the layers of debris it was covered under, a mere touch of the PWR glyph and a reassuring message appeared...

16.01.2015: tremble in fear, puny sidewalk
not sure what, but that pavement got something terrible coming it's way!

28.02.2014: dimpl
this here is the first version of DIMPL, a C++11 dependency injection framework purely written in template metaprogramming! check it out!

03.02.2014: finally some rower pics
took me ages, but I finally managed to find the pictures of my DIY rowing machine again!
here you go

29.10.2013: way to go dave!
and another time david cameron clearly demonstrates
his very personal understanding of democracy. this is even better than threatening the unions when they want to go on strike!

07.08.2013: new box
after about 8 years my old box has finally been replaced. and what a replacement! supermicro x10sae mobo, e3-1245v3 cpu, 16GB ECC ram @ 1.35V, intel 520 series SSD. awesome box, boots quicker than my netbook comes out of hibernate... thanks to ivy bridge there is *zero* fucking around with xorg drivers. and the coolest thing: the CPU has hradware transactional memory, which i bet is going to keep me occupied for quite a while...
update: "hradware" above is *not* a typo! ;)

30.01.2013: evil UEFI
just one more reason not to mess with UEFI, shims, bootloaders, signatures and all that crap. just switch it off in the bios. UEFI is a total anti-feature anyway...

23.01.2013: david cameron's EU speech
today mr cameron talked about the european union and britain's future in it. early in
his speech, mr cameron says:
But today the main, over-riding purpose of the European Union is different: not to win peace, but to secure prosperity.

mr cameron, you are greatly mistaken and i believe this mistake explains a lot of other things you say! the EU's original and primary goal and reason of existence is exactly to secure peace in europe. the common market is a tool towards that goal, prosperity may be windfall profit.

10.11.2012: best raspberry pi case ever
all over people are struggling to find the perfect raspberry pi enclosure. the ones that can annoyingly laser-cut theirs out of alloy sheets. some are slightly less blessed and need to make do with water-jet cut acrylic. of course the nerds just 3d-print one. the steampunks wittle them out of rosewood. but they got it all wrong! if you pay attention, you will notice that it actually comes with a perfect case!

15.05.2012: uk finally behin basel iii
took a while, but the uk is finally
not blocking basel iii anymore, so with some luck we will have the first effects within a year! excuse my cautious optimism, but that *is* good news...

13.05.2012: eu comission on the financial transaction tax
this the eu comission takes an even more positive stance on the financial transaction tax than in the past. if only people would listen!

09.04.2012: the madness of XML
XML is one of these *big* standards where you initially think this has all been thought through really well. then you start to look at the details. just found another marvel in how you declare namespaces, an example right from the spec:
<book xmlns='urn:loc.gov:books'
    <title>Cheaper by the Dozen</title>
looks good initially, but these namespace declarations are just normal attributes with QNames. so "xmlns:isbn" means local_name "isbn" in the namespace that the prefix "xmlns" resolves to ("http://www.w3.org/2000/xmlns/"). the other declaration however means local_name "xmlns" in the namespace of this element, which happens to be the one declared by this very declaration ("urn:loc.gov:books"). so any QName from the "xmlns" namespace can act as a namespace declaration, as well as an attribute with local_name "xmlns" from *any other* namespace. is that what namespaces are for? that declaring a specific fact (the domain of the namespace) is done *both* within that namespace *and* in *every other* one?

06.03.2012: working place ergonomics
best monitor stand *ever*:

05.12.2011: yesss!
yes please, I want
one of these. And while you're at it, do some sabretooth tigers as well!

05.09.2011: arghhh
you got to be kidding!

21.07.2011: last flight of the atlantis
ok, so this is it for the space shuttles. not that the shuttle is the most brilliant space program possible, but still worrying: will the shift to private sector space industry work? it might, but perhaps virgin and other will just find out that it is not worth the effort. perhaps the result is that space tech will have to take a back seat, then gets stepped down another notch with the odd global financial crisis, the eternal war on terror or peak oil being in the way. by the time that gets sorted out, the ISS might have dropped out of orbit and another incentive is gone. gloomy vision: in 25 years mankind's capabilities are reduced to replacing telecom and spy satelites in low orbit as they burn up, nothing more.

© robert lemmen