<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://mazin.cc/">
  <id>https://mazin.cc/</id>
  <title>mazin - weblog</title>
  <updated>2026-08-23T00:00:00Z</updated>
  <link rel="alternate" href="https://mazin.cc/" type="text/html"/>
  <link rel="self" href="https://mazin.cc/atom.xml" type="application/atom+xml"/>
  <author>
    <name>fredrik</name>
    <uri>https://mazin.cc</uri>
  </author>
  <entry>
    <id>tag:mazin.cc,2026-08-23:/2026/08/isle-of-skye/</id>
    <title type="html">isle of skye - a travel guide</title>
    <published>2026-08-23T00:00:00Z</published>
    <updated>2026-08-23T00:00:00Z</updated>
    <author>
      <name>fredrik &amp; katarina</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2026/08/isle-of-skye/" type="text/html"/>
    <content type="html">&lt;p&gt;We had the good fortune to spend a few nights in &lt;a href="https://en.wikipedia.org/wiki/Portree"&gt;Portree&lt;/a&gt; on the mighty &lt;a href="https://en.wikipedia.org/wiki/Isle_of_Skye"&gt;Isle of Skye&lt;/a&gt;. It is one of the major islands of the Inner Hebrides - a group of islands to the northwest in Scotland. Portree is the largest town on the island and perfectly positioned to do some exploring. We had rented a car but there are buses as well. To get to the more remote places a car (or a tour minibus) is necessary.&lt;/p&gt;

&lt;h3 id="accommodation"&gt;Accommodation&lt;/h3&gt;

&lt;p&gt;We were a bit late to arrange accomodation and it was rare and expensive. However we were lucky to find a room at the &lt;a href="https://www.kenmore-bedandbreakfast.co.uk/"&gt;Kenmore B&amp;amp;B&lt;/a&gt; for some £100 a night. This B&amp;amp;B is located some 10 minutes by foot from Portree centre. A basic room en suite with all you would need, a nice host and some great scottish breakfast. It was much better than we expected and at a really good price. Free parking just outside was also a nice feature.&lt;/p&gt;

&lt;h3 id="sights"&gt;Sights&lt;/h3&gt;

&lt;p&gt;There are lots to see so naturally you will have to choose a bit.&lt;/p&gt;

&lt;p&gt;One of the best drives was the one out to &lt;a href="https://en.wikipedia.org/wiki/Neist_Point"&gt;Neist Point&lt;/a&gt; - the westernmost point on the island. It is this really narrow road that goes on and on through a stunning landscape and at the end this small peninsula with a mighty rock and a lighthouse. On the way back we stopped in Glendale and the amazing &lt;a href="https://www.cafelephin.co.uk/"&gt;Cafe Lephin&lt;/a&gt; for a coffee. A local place with nice vibes and friendly staff.&lt;/p&gt;

&lt;p&gt;&lt;img src="../neist.jpg" alt="Neist Point" /&gt;&lt;/p&gt;

&lt;p&gt;Before Neist Point we visited the &lt;a href="https://www.malts.com/en-gb/distilleries/talisker"&gt;Talisker Distillery&lt;/a&gt; - the only one with some history on the island. We were lucky to get two spots on the 10 o’clock tour. It was a nice and informative tour that ended with a tasting of 3 drams. A nice touch that we have not seen before was the possibility for the designated driver to bring their samples in small bottles.&lt;/p&gt;

&lt;p&gt;&lt;img src="../talisker.jpg" alt="Talisker Distillery" /&gt;&lt;/p&gt;

&lt;p&gt;Also on the west side of things is the &lt;a href="https://www.dunvegancastle.com/"&gt;Dunvegan Castle&lt;/a&gt; - the main site for the MacLeod clan. The castle has been added to many times and for a while after the famine they had to let it go. But now it is again the main place for this clan which makes it a more interesting to visit. Quite expensive and the larger tourist buses can go here so more of a commercial site.&lt;/p&gt;

&lt;p&gt;That leads us to the castle of the Macdonalds - another important clan on the isle. The &lt;a href="https://en.wikipedia.org/wiki/Duntulm_Castle"&gt;Duntulm Castle&lt;/a&gt; on the north end of things. This is a ruin and it was abandoned already in the 18th century in favour of Monkstadt where the new head quarters was built - partly with stone from the old castle. This feels older than the Dunvegan one and is also free to visit. Just a stroll of some 100 meteres from the parking amongst sheep and ocean.&lt;/p&gt;

&lt;p&gt;Not far from the Duntulm Castle is the &lt;a href="https://skyemuseum.co.uk/"&gt;Skye Museum of Island Life&lt;/a&gt;. This is a handful of houses built in the style that was common in earlier days. And there are lots of interesting history to learn about here. Worth the visit.&lt;/p&gt;

&lt;p&gt;All over the place there are waterfalls and nice views. Just stop your car whenever the view looks promising and there is parking! Also the sheep - they are everywhere and they don’t particularly care about other kind of vehicles. Sometimes you just have to wait for a while….&lt;/p&gt;

&lt;p&gt;&lt;img src="../sheep.jpg" alt="Sheep" /&gt;&lt;/p&gt;

&lt;h3 id="food"&gt;Food&lt;/h3&gt;

&lt;p&gt;We had great food everywhere. Let’s single out three favourites.&lt;/p&gt;

&lt;h4 id="oyster-shed"&gt;Oyster Shed&lt;/h4&gt;

&lt;p&gt;After our visit to Talisker we went up the hill to this amazingly simplistic and overall great place - the &lt;a href="https://www.theoystershed.com/"&gt;Oyster Shed&lt;/a&gt;. It is really a shed that serves all the seafood you can imagine. We had natural and grilled oysters, softshell crabs, calamares, cod and lobster. All so fresh and tasty. And with some great views. And sheep nearby.&lt;/p&gt;

&lt;p&gt;&lt;img src="../shed.jpg" alt="View from Oyster Shed" /&gt;&lt;/p&gt;

&lt;h4 id="limited"&gt;1820 Limited&lt;/h4&gt;

&lt;p&gt;This establishment has set up in a former parish church built in 1820 - therefore the name. It was converted to a community hall in 1934 and then used for various purposes over the years. In 2019 the restaurant An talla mor 1820 (means the great hall 1820) opened up. It is a vibrant environment in this former church. It is busy and it was full when we arrived but we could hang out in the bar while waiting. We has steak pie and macaroni with some local beer. All nice. The vibes are perhaps better than the food but it was a really wholesome experience and the staff is really friendly. They have no own presence on the internet but you can find info on the usual social networks.&lt;/p&gt;

&lt;h4 id="sea-breeze"&gt;Sea Breeze&lt;/h4&gt;

&lt;p&gt;The last evening we headed for Sea Breeze - this is a place where you can’t book and the lines can be long. The location is in the midst of the harbor so quite right for such a venue. Perhaps due to the rain or that we were a bit early we managed to get the last table before the line started. Nice! We got a nice seafood platter with some nice wine to it.&lt;/p&gt;

&lt;p&gt;&lt;img src="../sea-breeze.jpg" alt="Sea food platter at Sea Breeze" /&gt;&lt;/p&gt;

&lt;h3 id="final-words"&gt;Final words&lt;/h3&gt;

&lt;p&gt;Isle of Skye was a really nice destination. The landscape is not far from those of the alps and the fjords, people are really friendly and there are lots of sheep.&lt;/p&gt;

</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2026-08-10:/2026/08/huge-raving-maniac/</id>
    <title type="html">huge raving maniac</title>
    <published>2026-08-10T00:00:00Z</published>
    <updated>2026-08-10T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2026/08/huge-raving-maniac/" type="text/html"/>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;Look, you know what I mean. You take a bunch of people who don’t seem any different from you and me, but when you add them all together you get this sort of huge raving maniac with national borders and an anthem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From &lt;a href="https://en.wikipedia.org/wiki/Monstrous_Regiment_(novel)"&gt;Monstrous Regiment&lt;/a&gt; by Terry Pratchett. Book 31 of discworld.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2026-08-09:/2026/08/abandoning-google-maps/</id>
    <title type="html">abandoning google maps</title>
    <published>2026-08-09T00:00:00Z</published>
    <updated>2026-08-09T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2026/08/abandoning-google-maps/" type="text/html"/>
    <content type="html">&lt;p&gt;I have been using a custom google maps to track the cities I have visited. As a part now of my goal to be less dependent on US tech I decided to move it to this site instead. I already have map support embedded in posts using &lt;a href="leafletjs.com"&gt;leaflet&lt;/a&gt;. I haven’t written about that but this work sort of extends on that.&lt;/p&gt;

&lt;h3 id="exporting-data-from-google"&gt;Exporting data from Google&lt;/h3&gt;

&lt;p&gt;This is easy enough. It is possible to export a &lt;a href="https://www.ogc.org/standards/kml/"&gt;KML&lt;/a&gt; file with all the data you have added. Now I knew that leaflet could work with &lt;a href="https://geojson.org/"&gt;geojson&lt;/a&gt; so I found a converter on the webz and converted the KML to geojson.&lt;/p&gt;

&lt;h3 id="deciding-on-format-at-rest"&gt;Deciding on format at rest&lt;/h3&gt;

&lt;p&gt;So I already had this set up with coordinates in the frontmatter triggering an embedded leaflet map for the posts having it. So it wouldn’t hurt to reuse that somehow. Another option would be to reference a geojson file directly. But mostly I will probably create maps from scratch. In the end I decided to add a new way to create posts based on a geojson file and then in the version controlled posts have the map information in the same way for these kind of posts.&lt;/p&gt;

&lt;h3 id="a-new-kind"&gt;A new kind&lt;/h3&gt;

&lt;p&gt;I already had two kinds of posts: &lt;strong&gt;article&lt;/strong&gt; and &lt;strong&gt;släkt&lt;/strong&gt;. I added a third one now called &lt;strong&gt;map&lt;/strong&gt;that outputs a full screen map based on coordinates in the front matter.&lt;/p&gt;

&lt;h3 id="generate-front-matter-from-geojson"&gt;Generate front matter from geojson&lt;/h3&gt;

&lt;p&gt;So I could have done a multi line edit from the geojson - after all my front matter format is not that different. But it is more fun to code something that can be used again potentially. So I created another nanoc script to create front matter from geojson. Below the data moprhing part. Otherwise it was much similar to the other creator scripts.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-ruby"&gt;def points_from_geo geojsonfile
  geo = JSON.load_file geojsonfile
  geo['features'].map do |one_feature|
    {
      lat: one_feature['geometry']['coordinates'][1],
      lng: one_feature['geometry']['coordinates'][0],
      name: one_feature['properties']['Name']
    }
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="layouting"&gt;Layouting&lt;/h3&gt;

&lt;p&gt;I put the maps in a new folder callse &lt;code&gt;content/maps&lt;/code&gt; and added a rule to the nanoc Rules file like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-ruby"&gt;compile '/**/maps/*.md' do
  filter :kramdown
  layout '/map.*'
  layout '/default.*'
  write item.identifier.without_ext + '/index.html'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is quite similar to articles but there is the map layout instead of the single one. This allows for the full screen map I am after. With some tweaks. This map layout is also used by call from the single layout so now it needs to be produce different sizes depnding on the caller. The width was hard wired in this layout before but I decided to remove it and use CSS to have different sizes depending on the kind of article. The main container has a class with the kind on so it is easy to have different seelctors for the map kind and the article kind. In the end I made the map special and everything else default. I already have the släkt kind that looks similar and there may be more in the future.&lt;/p&gt;

&lt;p&gt;The CSS turned out like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-css"&gt;.kind-map
{
    height: 100%;
    max-width: none;
}

#map
{
    height: 320px;
}

#map img
{
    max-width: none;
}

.kind-map #map
{
    height: 100%;
    width: 100%;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Yes the curly is on a new line cause I like it.)&lt;/p&gt;

&lt;h3 id="title-overlay"&gt;Title overlay&lt;/h3&gt;

&lt;p&gt;Finally I added a title overlay to the top right corner. (Layouts are &lt;a href="https://slim-template.github.io/"&gt;slim&lt;/a&gt;.)&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-slim"&gt;- if @item[:kind] == 'map'
  div.map-title-overlay
    = @item[:title]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And some CSS to make it look nice:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-css"&gt;.map-title-overlay
{
    position: absolute;
    z-index: 1000;
    top: 10px;
    right: 10px;
    font-size: larger;
    background-color: rgba(232, 232, 232, 0.85);
    padding: 10px;
    border-radius: 10px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="final-result"&gt;Final result&lt;/h3&gt;

&lt;p&gt;And see the final result &lt;a href="../../maps/visited-cities"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id="potential-extra-features"&gt;Potential extra features&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Add some kind of description and show it on click. Maybe an info icon or something.&lt;/li&gt;
  &lt;li&gt;Add backlink to mazin front page.&lt;/li&gt;
  &lt;li&gt;Add tags and cross link between posts and maps. Related postst in the info box perhaps.&lt;/li&gt;
  &lt;li&gt;Also generate full screen maps base on each post with a map in. And add a full screen link to the posts.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2026-05-23:/2026/05/cocktail-of-the-year-2026/</id>
    <title type="html">cocktail of the year 2026</title>
    <published>2026-05-23T00:00:00Z</published>
    <updated>2026-05-23T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2026/05/cocktail-of-the-year-2026/" type="text/html"/>
    <content type="html">&lt;h3 id="contessa"&gt;Contessa&lt;/h3&gt;

&lt;p&gt;Is that time of year when it is time to decide the cocktail of the year. Last year - of course - San Remo was the cocktail of the year. This summery thing suitable for the sun. However the times are not getting better so this year we need something heavier. I’ve been into negroni a bit lately but I found it a bit too bitter from the campari. So what could be better then a negroni where the campari has been replaced by aperol? In comes the contessa. This sounds italian. The word means countess in italian. Nevertheless it was created in Boston quite recently by bartender John Gertsen. Here is &lt;a href="https://www.youtube.com/watch?v=dbx3Wpdsm3w"&gt;a nice ted talk&lt;/a&gt; with him from 2010. And here a nice &lt;a href="http://archives.wbur.org/publicradiokitchen/2010/08/20/meet-your-bartender-drinks-john-gertsen/index.html"&gt;public radio kitchen post&lt;/a&gt; also from 2010 found in the archives. So what is a contessa? It is equal amounts of gin, dry vermouth and aperol. Kinda like a negroni or perhaps a cardinale. Perhaps the name is a wink to the cardinale? Browsing recipes on the internet there are a few that uses sweet vermouth instead of dry but the more authorative sources like &lt;a href="https://101mixology.com/recipe/contessa-37"&gt;101mixology&lt;/a&gt; and &lt;a href="https://www.diffordsguide.com/cocktails/recipe/13343/contessa"&gt;Difford’s Guide&lt;/a&gt; uses dry. I tried both and they are good in different ways but the dry one is perhaps a bit better.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2026-02-14:/2026/02/2026-interrail/</id>
    <title type="html">2026 february interrail</title>
    <published>2026-02-14T00:00:00Z</published>
    <updated>2026-02-14T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2026/02/2026-interrail/" type="text/html"/>
    <content type="html">&lt;p&gt;A little report from the latest interrail trip of mine. Third time in a row now I wanted to go to &lt;a href="https://fosdem.org/2026/"&gt;fosdem&lt;/a&gt; in Brussels. The main open source event in Europe. I wrote a bit about it in &lt;a href="../fosdem-2026"&gt;another post&lt;/a&gt;. Me and my partner decided to meet in Paris and spend a week there thereafter. And then I wanted to visit my daughter in Glasgow. I will spare you the details of lunches, dinners, museums and such and focus on the actual trip. I had a 10-day card to one entry per day.&lt;/p&gt;

&lt;h3 id="day-1---stockholm---malm---travemnde"&gt;Day 1 - Stockholm - Malmö (- Travemünde)&lt;/h3&gt;

&lt;p&gt;As I was catching the late ferry to Travemünde I set out from Stockholm after lunch. An uneventful but somewhat late train took me to Malmö with lots of time to spend before getting to the ferry. Getting to the ferry terminal in Malmö is a bit of a sad story. There are local buses but you need to change somewhere and it takse some 40 minutes to get there. Once leaving the bus the tiny ferry terminal is right there. Checking in and then waiting for shuttle bus to the actual ferry. I was the only foot passenger on a thursday in late January.&lt;/p&gt;

&lt;h3 id="day-2---travemnde---hamburg---kln---brussels"&gt;Day 2 - Travemünde - Hamburg - Köln - Brussels&lt;/h3&gt;

&lt;p&gt;On this day all trains would be late or cancelled. Not great PR for train travelling. I waited for the shuttle bus at the reception of the ferry and when it finally came the driver realized that I could catch my train if he drove me to the old train station for the Skandinavienkai (I realized when returning - more on that later) and sneak me out through a back door. Otherwise my plans would have blown up straight away. The train was somewhat late to Hamburg but no worries I had plenty of time for my train to Köln via Hannover. But the train from Hannover and onwards was cancelled. It seemed to be problems for all trains going that route. This was bad news since I needed that train to get to my planned train to Brussels. The direct train to Köln would miss it by some 10 minutes. And there is only one train every other hour from Köln to Brussels. So I got on the direct train to Köln instead. It turned out to be quite late and so was the train from Frankfurt towards Brussles. But not late enough. The next train to Brussels it had to be. Adding to it all was a strike in Belgium. From the last stop in Germany people were standing and sitting on floors. Quite busy. I had figured this out early and managed to get a seat reservation. Normally you don’t need to have one on these trains.&lt;/p&gt;

&lt;h3 id="day-3---brussels---paris"&gt;Day 3 - Brussels - Paris&lt;/h3&gt;

&lt;p&gt;A continental Eurostar from Brussels to Paris. Uneventful really.&lt;/p&gt;

&lt;h3 id="day-4---paris---london"&gt;Day 4 - Paris - London&lt;/h3&gt;

&lt;p&gt;A late departure had me stay a night in London so I took the tunnel train (that I despise) in order to get there. Waiting for Eurostar in Paris is much better than in London though. There is actually some space to move around in. I noticed thath security was a bit tougher and had to remove laptops and belts and such. Just like flying…&lt;/p&gt;

&lt;h3 id="day-5---london---glasgow"&gt;Day 5 - London - Glasgow&lt;/h3&gt;

&lt;p&gt;I arrived in London on a Saturday and sadly the Caledonian sleeper does not run on Saturdays. So I took the first Sunday morning train out of Glasgow. A bit od luck here - the day before the Euston to Watford part had been competely broken for some time. The route is really beautiful from the lake district and northwards.&lt;/p&gt;

&lt;h3 id="day-6---glasgow---edinburgh---glasgow"&gt;Day 6 - Glasgow - Edinburgh - Glasgow&lt;/h3&gt;

&lt;p&gt;A waste to spend a day on this but otherwise the day would have been waste. Took the fast train there and the slow train back.&lt;/p&gt;

&lt;h3 id="day-7---glasgow---edinburgh---newcastle---amsterdam"&gt;Day 7 - Glasgow - Edinburgh - Newcastle (- Amsterdam)&lt;/h3&gt;

&lt;p&gt;It felt wise to check the status in the morning and it turned out that there were somde delays due to have rains. So I leftsomewhat earlier then I had initially thought. The Newcastle - Amsterdam ferry leaves at 17 and there is a shuttle bus from the train station at 14:30 and another one at 15:30. I aimed for the early one. The train route involved a change in Edinburgh and also a late train that changed tracks right before departure. Hectic. Also a scenic view by the ocean parts of the route from Edinburgh and south.&lt;/p&gt;

&lt;h3 id="day-8---amsterdam---hannover"&gt;Day 8 - Amsterdam - Hannover&lt;/h3&gt;

&lt;p&gt;In Amsterdam there is also a shuttle bus going to Amsterdam Centraal. Very convenient. And what a nice setting for the main train station on the waterside. Magnificent. I only had ont train to day - 4 hours to Hannover where I was gonna spend the night.&lt;/p&gt;

&lt;h3 id="day-9---hannover---hamburg---lbeck---travemnde---malm"&gt;Day 9 - Hannover - Hamburg - Lübeck - Travemünde (- Malmö)&lt;/h3&gt;

&lt;p&gt;Getting from Hannover to the ferry terminal in Travemünde involves two changes of trains. It seems that sometimes the train from Hamburg transforms into the Travemünde one in Lübeck. While getting on the train in Lübeck I was still of the impression that I should get off at Travemünde-Skandinavienkai. But on the train when approaching Lübeck-Kücknitz it was announced that this was the proper station to get off and then find a shuttle bus. There was supposed to be signs. I didn’t see any signs so started waiting by the first bus stop I saw. Two buses and two bus drivers later I had realized that my station (the Elbingstraße) was indeed some bit further away and that my bus should have the number 50. This bus goes all the way from Lübeck so it is probably easiest to just get on there and ride it to the end station.&lt;/p&gt;

&lt;h3 id="day-10-malm---stockholm"&gt;Day 10 Malmö - Stockholm&lt;/h3&gt;

&lt;p&gt;A morning train out of Malmö homewards!&lt;/p&gt;

&lt;h3 id="reflections"&gt;Reflections&lt;/h3&gt;

&lt;p&gt;Some ferries are harder than others. Both Malmö and Travemünde is unconvenient for train travellers. Much like Rostock, Sassnitz and Gdansk from other train trips. They are built for vehicles - mostly the larger sort but obviously cars and buses works fine as well.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2026-02-07:/2026/02/paris-restaurants/</id>
    <title type="html">a couple of nice paris restaurants</title>
    <published>2026-02-07T00:00:00Z</published>
    <updated>2026-02-07T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2026/02/paris-restaurants/" type="text/html"/>
    <content type="html">&lt;p&gt;We spent a couple of days in Paris and had some really great food. As always in France… All the places we visited was really good but three of them stood out.&lt;/p&gt;

&lt;h3 id="bistro-des-livres"&gt;Bistro des Livres&lt;/h3&gt;

&lt;p&gt;This was our last impression of France over lunch before moving on in different directions. It is a nice small restaurant not far from Île de la Cité on the southern side of the Seine on cozy side street Rue Galande. The theme of the interior is - as the name suggests - books. We had Canard Confit (duck basically) and a Sauciss Purée (sausage with mashed potatoes). The mash could be upgraded to &lt;em&gt;Aligot&lt;/em&gt; which turned out to be a cheese fortified mash. Before that we shared a baked camembert. Definitely a place to return to.&lt;/p&gt;

&lt;p&gt;It has two sister restaurants: Bistro des Lettres and Bistro des Poèmes and you can read more about them &lt;a href="https://bistrodeslettres.com/"&gt;here&lt;/a&gt;. Maybe the locations of the other two suits you better.&lt;/p&gt;

&lt;p&gt;&lt;img src="../livres.jpg" alt="Image of sausage and mash" /&gt;&lt;/p&gt;

&lt;h3 id="huitrerie-rgis"&gt;Huitrerie Régis&lt;/h3&gt;

&lt;p&gt;Last time in Paris we visited this &lt;a href="https://huitrerie-regis.com/en/home/"&gt;tiny oyster place&lt;/a&gt; with perhaps 8 tables. We liked it so much so we decided to come back this time as well. It is mostly oysters and some other shellfish on the menu and they have really nice wine and champagne to go with it. We started with foie gras and &lt;a href="https://en.wikipedia.org/wiki/Taramasalata"&gt;tarama&lt;/a&gt; (a meze made from roe). We then shared a platter of 12 oysters of 3 different kinds. It is a nice number as you get to taste each oyster twice.&lt;/p&gt;

&lt;p&gt;&lt;img src="../regis.jpg" alt="platter of oysters" /&gt;&lt;/p&gt;

&lt;h3 id="ambassade-de-bourgogne"&gt;Ambassade de Bourgogne&lt;/h3&gt;

&lt;p&gt;After the great oysters we moved on to this &lt;a href="https://www.ambassadedebourgogne.com/"&gt;nice winebar&lt;/a&gt; dedicated exclusively to wines from Bourgogne. We tried a Givry and another one we already forgot what it was. They were quite similar. We also had some really nice cheese to go with it. I have learned at some point that you are supposed to have white wine with cheeses but here there was one cheese platter for red wines and another one for whites. Makes sense.&lt;/p&gt;

&lt;p&gt;&lt;img src="../bourgogne.jpg" alt="bourgogne wine bottles" /&gt;&lt;/p&gt;

&lt;h3 id="honorable-mentions"&gt;Honorable mentions&lt;/h3&gt;

&lt;p&gt;From the map it is easy to see where our hotel is located. The &lt;a href="http://www.hotel-paris-univers.com/"&gt;Grand Hôtel de L’Univers&lt;/a&gt;. A really nice hotel with friendly staff that we came back to a second time.&lt;/p&gt;

&lt;p&gt;So it turned out that the restaurants we found close by were the best but we also made two excursions to restaurants worthy of mentioning.&lt;/p&gt;

&lt;p&gt;We had lunch one day at &lt;a href="http://escargotmontorgueil.com/"&gt;L’Escargot Montorgueil&lt;/a&gt; that we found while searching for escargots places. It has a huge snail on the wall above the restaurant that looks really nice. the food here was really fine but we was more impressed by the environment in the style of 1920s Paris perhaps. We had escargots (obviously - they had a few different kinds to choose from), scallops, canard and tartare. All good.&lt;/p&gt;

&lt;p&gt;Also from the 20s &lt;a href="https://www.lacoupole-paris.com/"&gt;La Coupole&lt;/a&gt; that was founded 1927 so almost 100 years ago. It brands itself as an &lt;em&gt;american bar&lt;/em&gt; which it surely may have been at one time. But now it feels really french. The interior is art deco with some nice art as well. And it is a really grand room buzzing with energy - waiters running around making sure that everything is fine. They seem to be into shellfish so we had an oyster plate to start with and then sea bass and salmon. And a bottle of Sancerre to go with that. The whole place felt a bit touristic but the food was really good so it made up for it. (It was also the only place on our trip where the waiter actually asked for tipping.)&lt;/p&gt;

&lt;p&gt;&lt;img src="../coupole.jpg" alt="wine glasses and cutlery from la coupole" /&gt;&lt;/p&gt;

&lt;p&gt;All photos by Katarina Östlund and excluded from the creative commons license below.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2026-02-01:/2026/02/fosdem-2026/</id>
    <title type="html">fosdem 2026</title>
    <published>2026-02-01T00:00:00Z</published>
    <updated>2026-02-01T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2026/02/fosdem-2026/" type="text/html"/>
    <content type="html">&lt;p&gt;So I made it to &lt;a href="https://fosdem.org/2026/"&gt;fosdem&lt;/a&gt; for the sixth time. Last year I never wrote anything about it but from 2 years ago there is a &lt;a href="/2024/02/fosdem-2024"&gt;nice report&lt;/a&gt;. There is also a short guide in there about how to survive the days at fosdem so I won’t repeat that again.&lt;/p&gt;

&lt;h3 id="day-1"&gt;Day 1&lt;/h3&gt;

&lt;p&gt;What is interesting to me changes from year to year but one thing that has been with me a lot over the last couple of years is the idea to have social networks that are not sponsored by corporations. Similar vibes as to the early days on the internet but more sophisticated. Thus I spent most of the first day in the &lt;a href="https://fosdem.org/2026/schedule/track/social-web/"&gt;&lt;em&gt;Social Web room&lt;/em&gt;&lt;/a&gt;. Many of the talks were mostly about advocacy for the fediverse. Nice in itself but somewhat repetetive over the day.&lt;/p&gt;

&lt;p&gt;First out was &lt;a href="https://mastodon.social/@pfefferle"&gt;Matthias Pfefferle&lt;/a&gt; - the creator of the Wordpress ActivityPub plugin - with the talk &lt;a href="https://fosdem.org/2026/schedule/event/XFTETA-federated-wordpress/"&gt;Democratise the fediverse&lt;/a&gt;. Large territories of the internet is powered by Wordpress so here is a great opportunity to get critical mass of adopters.&lt;/p&gt;

&lt;p&gt;Then came a somewhat similar talk by &lt;a href="https://hachyderm.io/@haubles"&gt;Hannah Aubry&lt;/a&gt; and &lt;a href="https://macaw.social/@andypiper"&gt;Andy Piper&lt;/a&gt; from the Mastodon organization called &lt;a href="https://fosdem.org/2026/schedule/event/HJYRFF-tending-the-herd/"&gt;Tending the herd: Community at Mastodon&lt;/a&gt;. They have received some critic for pushing so much for their own server (mastodon.social) on the mastodon home page. It is a tricky issue since making it easy to sign up and get started is important for the fediverse. Having to choose a server may be a hurdle too high for many normal users. Thus they have kept it. Also - as I understood it - for reasons of having a high load server to make it easier to see how the software behaces under pressure. In this talk they announced that they are working towards pushing for a “best match” server instead based on the users language and location. Opt-in on the servers end. Good news indeed.&lt;/p&gt;

&lt;p&gt;I sneaked away from the room after this talk and listened to the &lt;a href="https://fosdem.org/2026/schedule/event/AGWUVH-mercurial-aint-you-dead-yet/"&gt;Mercurial 20 years and counting&lt;/a&gt; talk about the state of mercurial version control. For me it was the first distributed version control systsem I tried back in the days and it still seem to have some advantages over git. Maybe try it out again at some point.&lt;/p&gt;

&lt;p&gt;Back to the social web room for three 10 minute talks.&lt;/p&gt;

&lt;p&gt;First out &lt;a href="https://cosocial.ca/@evan"&gt;Evan Prodromou&lt;/a&gt; &lt;a href="https://fosdem.org/2026/schedule/event/WNDQUQ-tags-pub/"&gt;presenting tags.pub&lt;/a&gt; a new take on the problem with tags. As it is now the only posts tagged with something you get to see are those that has passed by the server you live on. With this new approach each tag is a user on the activity pub server tags.pub. So instead of following a tag on your own server you can follow this user that collects all the relevant posts over all (or most) servers.&lt;/p&gt;

&lt;p&gt;Then &lt;a href="https://chaos.social/@cypherhippie"&gt;Paul Fuxjäger&lt;/a&gt; about &lt;a href="https://fosdem.org/2026/schedule/event/RZRZ9P-increasing_long_term_stability_of_relations_between_fediverse_identities_using_s/"&gt;Increasing Long Term Stability of Relations Between Fediverse Identities using SSI&lt;/a&gt;. Obviously it would be good to have long running identities not directly connected with specific servers. But mostly my take away from this talk is that this is something I would like to learn more about.&lt;/p&gt;

&lt;p&gt;Finally in this cluster of talks Django Doucet &lt;a href="https://fosdem.org/2026/schedule/event/QK7XSV-activitypub-c2s/"&gt;about the client to server ActivityPub&lt;/a&gt; that exists but is barely used. Each platform has built their own API for theis own needs. &lt;em&gt;Normies need their apps.&lt;/em&gt; But what if one client would be all that we need? Utilising the standard that was supposed to solve this. Not without concerns this one. I mean this client would need to be able to present and interact with a multitude of different content types.&lt;/p&gt;

&lt;p&gt;More talks happened but I will skip on to the &lt;a href="https://fosdem.org/2026/schedule/event/3QHALR-bonfire_building_modular_consentful_and_federated_social_networks/"&gt;Bonfire talk&lt;/a&gt;. This is an interesting effort to build a federated space for communities. The design is very modular so the idea is to pick and choose what things to build with and on. Would have been interesting to see a little more hands on.&lt;/p&gt;

&lt;p&gt;The last talk of the day for me turned out to be &lt;a href="https://hollo.social/@hongminhee"&gt;Hong Minhee&lt;/a&gt; about &lt;a href="https://fosdem.org/2026/schedule/event/KSEUZT-fedify/"&gt;Fedify: Building ActivityPub servers without the pain&lt;/a&gt;. So he started ouy building his own singel user acivity pub server but realised that there is so much pain building a thing like this. So all the pain was extracted to this little framework called Fedify.&lt;/p&gt;

&lt;h3 id="day-2"&gt;Day 2&lt;/h3&gt;

&lt;p&gt;I started the day with two talks in the Declarative and Minimalistic Computing room. The first one was about a programming language I have barely heard about before: crystal. &lt;a href="https://fosdem.org/2026/schedule/event/N3AFSF-crystal/"&gt;&lt;em&gt;A language for humans and computers&lt;/em&gt;&lt;/a&gt; by &lt;a href="https://fosstodon.org/@straightshoota"&gt;Johannes Müller&lt;/a&gt;. Turns out that Crystal started with the idea of getting a statically compiled Ruby. So some things added along those lines:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;static typing&lt;/li&gt;
  &lt;li&gt;cool concerrency using a spawn keyword&lt;/li&gt;
  &lt;li&gt;everything in the language is async by default (which is what you want anyway….)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All in all looked pretty cool and is something I may want to try out at some point. Although Gleam is still on top of that list.&lt;/p&gt;

&lt;p&gt;The second talk was about &lt;a href="https://fosdem.org/2026/schedule/event/ZPFNKB-lua-ui/"&gt;&lt;em&gt;Building a minimal cross-platform terminal UI library&lt;/em&gt;&lt;/a&gt; by Thijs Schreijer. Quite cool how they built something on top of Lua and obviously had some issues with Windows.&lt;/p&gt;

&lt;p&gt;Then I tried to get in to the DNS room but it was full.&lt;/p&gt;

&lt;p&gt;Plan B can often be a main track and also so this time. I went into La Fontaine to listen to Sal Kimmich about &lt;a href="https://fosdem.org/2026/schedule/event/NS7DF7-hidden-life-of-infrastructure/"&gt;&lt;em&gt;The Hidden Life of Infrastructure: How Control Moves Through Code, Chips, and Nations&lt;/em&gt;&lt;/a&gt;. This was one of these talks that used to be a couple of hours and was cut down on-the-fly during the talk. The result was quite fragemented although the content was really interesting. I would have loved to hear either the long version or a more curated one hour summary. Still a super interesting topic about the entirety of infrastructure. The talk was organized around a book by the speaker. Perhaps I’ll pick it up.&lt;/p&gt;

&lt;p&gt;Then I tried fo the in to the DNS room again but it was full.&lt;/p&gt;

&lt;p&gt;Then I tried to get back into La Fontaine for the talk about reverse engineering the spotify protocol. But it was now full.&lt;/p&gt;

&lt;p&gt;I then decided to get back to the Declarative and Minimalistic Computing room for an interesting talk about DSLs in Lisp. But it was full.&lt;/p&gt;

&lt;p&gt;Three full rooms in a row is my maximum so I retired back to the hang out areas in the middle to write these words.&lt;/p&gt;

&lt;p&gt;Another attempt - now I was early to the &lt;a href="https://fosdem.org/2026/schedule/track/retrocomputing/"&gt;&lt;em&gt;Retrocomputing&lt;/em&gt;&lt;/a&gt; room and managed to grab a chair. A nice talk about &lt;a href="https://fosdem.org/2026/schedule/event/B7BVVJ-eliza_rewriting_the_original_ai_chatbot_from_60_years_bc_before_chatgpt/"&gt;rewriting 60 year old Eliza in Javascript&lt;/a&gt; by Steven Goodwin. He seemed familiar so I have probably attended one of his revious 28 talks at fosdem. The original Eliza was not written in Lisp but in some other old language called MAD something. A really compact thing (that made me think of APL for some reason) that required 5-10 times as much Javascript for a line-by-line port. And the problem with the lack of a GOTO mechanism in Javascript.&lt;/p&gt;

&lt;p&gt;Then off to Janson for the two last talks before heading towards a train out of Belgium. The first one was about the &lt;a href="https://fosdem.org/2026/schedule/event/XWSW3R-the_geopolitics_of_open_source_software/"&gt;geopolitics of code&lt;/a&gt;. At a time when open source has made it global - contributors are now from all over the world - the political situation has become less global. It is unfortunate and may result in defragmentation yet again. Is it wise to store open source software on github - a clearly american effort? China is building concurrent infrastructure in order to be independent of the west. What can Europe do? Be a positive force in this mess?&lt;/p&gt;

&lt;p&gt;Finally the last talk I attended was about esoteric programming languages called &lt;a href="https://fosdem.org/2026/schedule/event/KX9P7J-art-of-esoteric-code/"&gt;&lt;em&gt;The Hacker Folk Art of Esoteric Code&lt;/em&gt;&lt;/a&gt; by &lt;a href="https://mastodon.social/@rottytooth"&gt;Daniel Temkin&lt;/a&gt;. A really great topic to end the conference with. The usual suspects like brainfuck and piet. But also a pretty new one by the speaker called &lt;a href="https://esolangs.org/wiki/Rivulet"&gt;rivulet&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id="ending-thoughts"&gt;Ending thoughts&lt;/h3&gt;

&lt;p&gt;As it is this conference is hectic and it is hard to expect anything from it really. And there is always something unexpected happening. It is both tiresome (all these people just being in the way and occupying the interesting rooms) and energizing (all these people being there with so much energy about open source). This year I managed to attend 18 talks and they were all nice to listen to. Probably reflecting where I am - it turned out to be a bit too much open source advocacy and a bit too little tech stuff. I made up with that by doing some coding in the middle of the second day.&lt;/p&gt;

&lt;p&gt;Over and out and see you next year!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2025-10-29:/2025/10/around-the-baltic/</id>
    <title type="html">around the baltic - 2025 edition</title>
    <published>2025-10-29T00:00:00Z</published>
    <updated>2025-10-29T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2025/10/around-the-baltic/" type="text/html"/>
    <content type="html">&lt;p&gt;I wrote an original post back in 2021 about how to get around the baltic with train and only train and thought it would be about time for an updated version for 2025. It will avoid Russia and use a ferry from Helsinki to Tallin instead so it will be a bit faster perhaps.&lt;/p&gt;

&lt;p&gt;Times are from some random day - I have not checked that they really fit togethere in a real world scenario.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 1&lt;/td&gt;
      &lt;td&gt;06:22&lt;/td&gt;
      &lt;td&gt;Stockholm C&lt;/td&gt;
      &lt;td&gt;12:37&lt;/td&gt;
      &lt;td&gt;Umeå&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 1&lt;/td&gt;
      &lt;td&gt;13:32&lt;/td&gt;
      &lt;td&gt;Umeå&lt;/td&gt;
      &lt;td&gt;16:57&lt;/td&gt;
      &lt;td&gt;Boden&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 1&lt;/td&gt;
      &lt;td&gt;17:16&lt;/td&gt;
      &lt;td&gt;Boden&lt;/td&gt;
      &lt;td&gt;18:40&lt;/td&gt;
      &lt;td&gt;Haparanda&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 1&lt;/td&gt;
      &lt;td&gt;18:50&lt;/td&gt;
      &lt;td&gt;Haparanda&lt;/td&gt;
      &lt;td&gt;20:13&lt;/td&gt;
      &lt;td&gt;Tornio&lt;/td&gt;
      &lt;td&gt;bus here&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 1&lt;/td&gt;
      &lt;td&gt;22:16&lt;/td&gt;
      &lt;td&gt;Tornio&lt;/td&gt;
      &lt;td&gt;10:45&lt;/td&gt;
      &lt;td&gt;Helsinki&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 2&lt;/td&gt;
      &lt;td&gt;13:30&lt;/td&gt;
      &lt;td&gt;Helsinki&lt;/td&gt;
      &lt;td&gt;15:30&lt;/td&gt;
      &lt;td&gt;Tallin&lt;/td&gt;
      &lt;td&gt;ferry&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 2&lt;/td&gt;
      &lt;td&gt;18:30&lt;/td&gt;
      &lt;td&gt;Tallin&lt;/td&gt;
      &lt;td&gt;22:02&lt;/td&gt;
      &lt;td&gt;Valga&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 3&lt;/td&gt;
      &lt;td&gt;05:43&lt;/td&gt;
      &lt;td&gt;Valga&lt;/td&gt;
      &lt;td&gt;08:05&lt;/td&gt;
      &lt;td&gt;Riga&lt;/td&gt;
      &lt;td&gt;three trains a day&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 3&lt;/td&gt;
      &lt;td&gt;16:55&lt;/td&gt;
      &lt;td&gt;Riga&lt;/td&gt;
      &lt;td&gt;21:03&lt;/td&gt;
      &lt;td&gt;Vilnius&lt;/td&gt;
      &lt;td&gt;one train a day&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 4&lt;/td&gt;
      &lt;td&gt;12:35&lt;/td&gt;
      &lt;td&gt;Vilnius&lt;/td&gt;
      &lt;td&gt;14:52&lt;/td&gt;
      &lt;td&gt;Mockava&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 4&lt;/td&gt;
      &lt;td&gt;15:25&lt;/td&gt;
      &lt;td&gt;Mockava&lt;/td&gt;
      &lt;td&gt;19:41&lt;/td&gt;
      &lt;td&gt;Warsaw&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 4&lt;/td&gt;
      &lt;td&gt;20:38&lt;/td&gt;
      &lt;td&gt;Warsaw&lt;/td&gt;
      &lt;td&gt;23:03&lt;/td&gt;
      &lt;td&gt;Gdansk&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 5&lt;/td&gt;
      &lt;td&gt;06:14&lt;/td&gt;
      &lt;td&gt;Gdansk&lt;/td&gt;
      &lt;td&gt;09:20&lt;/td&gt;
      &lt;td&gt;Poznan&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 5&lt;/td&gt;
      &lt;td&gt;09:35&lt;/td&gt;
      &lt;td&gt;Poznan&lt;/td&gt;
      &lt;td&gt;11:33&lt;/td&gt;
      &lt;td&gt;Szczecin&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 5&lt;/td&gt;
      &lt;td&gt;13:01&lt;/td&gt;
      &lt;td&gt;Szczcecin&lt;/td&gt;
      &lt;td&gt;13:39&lt;/td&gt;
      &lt;td&gt;Pasewalk&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 5&lt;/td&gt;
      &lt;td&gt;14:19&lt;/td&gt;
      &lt;td&gt;Pasewalk&lt;/td&gt;
      &lt;td&gt;15:41&lt;/td&gt;
      &lt;td&gt;Stralsund Hbf&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 5&lt;/td&gt;
      &lt;td&gt;16:16&lt;/td&gt;
      &lt;td&gt;Stralsund Hbf&lt;/td&gt;
      &lt;td&gt;19:28&lt;/td&gt;
      &lt;td&gt;Berlin Hbf&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 5&lt;/td&gt;
      &lt;td&gt;20:10&lt;/td&gt;
      &lt;td&gt;Berlin Hbf&lt;/td&gt;
      &lt;td&gt;07:00&lt;/td&gt;
      &lt;td&gt;Malmö C&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Day 6&lt;/td&gt;
      &lt;td&gt;08:07&lt;/td&gt;
      &lt;td&gt;Malmö C&lt;/td&gt;
      &lt;td&gt;12:34&lt;/td&gt;
      &lt;td&gt;Stockholm C&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;There you go - almost a week on the train except the ferry now to avoid Russia. Some things are better and some things are worse than last time.&lt;/p&gt;

&lt;p&gt;On the plus side:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;there is a night train now from Tornio to Helsinki. No other trains seems to operate from Tornio at this point but this will change. Finland is &lt;a href="https://railmarket.com/news/infrastructure/33533-finland-a-shift-of-railways-to-european-track-is-back-on-the-table-due-to-security-concerns"&gt;thinking about changing&lt;/a&gt; their rail guage away from the Russian standard to the European standard. This will make it possible to operate trains across the Swedish-Finnish border.&lt;/li&gt;
  &lt;li&gt;more options from Tallin to Riga. (But no direct option no more.)&lt;/li&gt;
  &lt;li&gt;this time we make use of the night train from Berlin to Malmö and in the end we are one hour earlier in Stockholm.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the minus side:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Day 2 in the 2021 schedule ended in St Petersburg. This schedule is already in Valga at the Estonian border to Latvia. Good but then the trains through Latvia and Lthuania is so sparse that we end up day 4 in Gdansk anyway and 3 hours later this time.&lt;/li&gt;
  &lt;li&gt;Less train options in Poland. There used to be a direct from Bialystok to Gdansk. Not anymore so we need the Warsaw connection instead. Same from Gdansk to Szczecin.&lt;/li&gt;
  &lt;li&gt;Two more legs going up to 19 now.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;6 days is a long time to spend on trains and to make it more interesting and actually experiencing things perhaps 2 weeks would be more appropriate. Or make smalle circuits based on this. For exampe ferry from Stockholm to Tallin, then train through the 3 baltic states down to Klaipeda and the ferry back to Karlshamn.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2025-09-22:/2025/09/notes-on-software-development-and-ai/</id>
    <title type="html">notes on software development and ai</title>
    <published>2025-09-22T00:00:00Z</published>
    <updated>2025-09-22T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2025/09/notes-on-software-development-and-ai/" type="text/html"/>
    <content type="html">&lt;p&gt;Just some random notes on the use of large language models to assist in coding. I have not worked with an agent so can not really comment on that. I like to interact with the text, the actual characters, that form a program. I am not that fond of verbose programming languages and I am not that interested in getting help writing the code. It would remove some of the fun and satisfaction with coding. I have used some AIs as better search engines and it has been quite useful for some usages and quite useless for others. I don’t really mind people using tools to generate and write code. If they like it it is good for them I guess. I use some myself when working on verbose languages like Java or Kotlin. Things I do to pay the bills… So on to some observations.&lt;/p&gt;

&lt;h3 id="increased-speed"&gt;Increased speed&lt;/h3&gt;

&lt;p&gt;There seems to be a general opinion that software development needs to be done faster and that it would be good if coders could speed up a bit. I think this is a mistake. Most organizations that has been around for more than 3-5 years have systems they call &lt;strong&gt;legacy&lt;/strong&gt; - these are systems that are hard to maintain and evolve. This typically happens when a serie of initiatives - often with different sets of developers - has enhanced the system with new features. (Also note that when I write systems I mean it in an abstract way. It can just as well be a forest of micro services as a monolith. It will just be different kinds of mess.) What if the developers on thes legacy systems had moved a bit slower and made sure that the code was of high quality, well tested and maintainable. Perhaps the need to replace that legacy system wouldn’t be that high. I would argue that moving a bit slower and with quality in mind will make us move faster in the long run. Also - when you think about it - large language models are based on code that make up the software we have today so using them will likely just produce more systems of the same kind. Which leads me on to….&lt;/p&gt;

&lt;h3 id="how-does-this-really-work"&gt;How does this really work?&lt;/h3&gt;

&lt;p&gt;I am no expert in large language models but I understand that they need to train on real things to produce reasonable outcomes. So if you get help to write some code it will likely be similar to some code that has already been written by a bunch developers somehwere (that will not get any credit for this). I guess this is fine if you want results fast but for any orgnization that wants to create an edge over competitiors or just simply do something unique it won’t happen.&lt;/p&gt;

&lt;h3 id="who-is-responsible"&gt;Who is responsible?&lt;/h3&gt;

&lt;p&gt;It doesn’t feel right to me that people are writing code that they could not write themselves. Who is responsible for this piece of code? When it doesn’t work there needs to be a human taking responsibility for the code. I don’t want to do that with code I don’t understand. (In a distant future with sentient AIs this may be different of course. Then they can have legal statuses by themselves.)&lt;/p&gt;

&lt;h3 id="ending-notes"&gt;Ending notes&lt;/h3&gt;

&lt;p&gt;It may sound that I am complaining but I am not. I just see that - with or without the help of LLMs - we are gonna continue write mediocre systems in the future as well. For me this is great - I don’t mind messing around with legacy code - I find it kind of fun actually. I also don’t mind having a job for some years more. What we could do instead of trying and failing to replace ourselves with LLMs is to actually raise the level of abstraction of programming languages. That would increase both the speed and the quality at the same time.&lt;/p&gt;

&lt;p&gt;Over and out for now.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2025-01-27:/2025/01/kotlin-concurrency-revisited/</id>
    <title type="html">kotlin concurrency revisited</title>
    <published>2025-01-27T00:00:00Z</published>
    <updated>2025-01-27T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2025/01/kotlin-concurrency-revisited/" type="text/html"/>
    <content type="html">&lt;p&gt;I &lt;a href="../../../2024/12/kotlin-concurrency"&gt;wrote a while ago&lt;/a&gt; about the nice &lt;a href="https://kotlinlang.org/docs/coroutines-guide.html"&gt;concurrency features in kotlin&lt;/a&gt;. And as with all things there are some things that shine less when you get to use it for a while. I became a bit suspocious when I browsed the logs for a place where we do concurrenct calls. They seemed to coming on one after the other anyway and not all at the same time as expected. So I started to investigate and it turns out that kotlin concurrency out of the box only runs on one thread and will not be very concurrenct in the way you may expect. But fear not - there are ways to work around it.&lt;/p&gt;

&lt;p&gt;When you start a concurrecnt block it is possible to pass in a CoroutineContext parameter to specify in what manner you would want the parallelism to proceed. To get a new single thread context you can pass in &lt;code&gt;newSingleThreadContext("Name of a thread")&lt;/code&gt;. Ot you can create your own Dispatcher to actually pass things on between the threads. If you are on a thread local centric framework like Spring this may be necessary in order to pass on security context, logging context and similar. So in order to get things running in parallel you need to read up on these things and implement them.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2025-01-24:/2025/01/termini-cocktail/</id>
    <title type="html">termini</title>
    <published>2025-01-24T00:00:00Z</published>
    <updated>2025-01-24T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2025/01/termini-cocktail/" type="text/html"/>
    <content type="html">&lt;p&gt;All my loyal readers may remember the &lt;a href="../centrale-cocktail/"&gt;centrale cocktail&lt;/a&gt; that I wrote about a few weeks ago. It actually started with this one that didn’t have a name at the time. Now I call it Termini and it is the alcohol heavy cousin of centrale.&lt;/p&gt;

&lt;p&gt;Ingredients:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;3 parts bourbon&lt;/li&gt;
  &lt;li&gt;2 parts cointreau&lt;/li&gt;
  &lt;li&gt;1 part coffee liqueur&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How to do it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;put a big ice block in a martini glass&lt;/li&gt;
  &lt;li&gt;pour the ingredients on to the ice&lt;/li&gt;
  &lt;li&gt;mix gently with a spoon&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And termini - of course - is the main train station of Roma so it is a kind of centrale. And ther you go!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2025-01-06:/2025/01/clear-the-css-cache/</id>
    <title type="html">clear the css cache</title>
    <published>2025-01-06T00:00:00Z</published>
    <updated>2025-01-06T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2025/01/clear-the-css-cache/" type="text/html"/>
    <content type="html">&lt;p&gt;So on this site I sometimes change the stylesheet. But whenever a browser has seent the file ones it may decide to cache it forever. So I decided to do something about it. The most obvious way to solve it is to make sure that the styletsheet file has a different name whenever it changes (or - as in this case - when there is a new version). A good unique thing to use here is the version hash from the git repo. I decided to go for the naming schems &lt;code&gt;stylesheet.&amp;lt;hash&amp;gt;.css&lt;/code&gt;. For example &lt;code&gt;stylesheet.2bbcf48.css&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As the faithful reader &lt;a href="/2024/04/this-site/"&gt;already knows&lt;/a&gt; I use &lt;a href="https://nanoc.app/"&gt;nanoc&lt;/a&gt; to generate this static website and it turned out that I only needed to change two things.&lt;/p&gt;

&lt;p&gt;First off the &lt;code&gt;Rules&lt;/code&gt; file. This is where to define how different files are generated based on the content. For all file types that don’t change in generated form there is the simple rule at the end of the file:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-ruby"&gt;compile '/**/*' do
  write item.identifier.to_s
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes sure to write all files that are not treated elsewhere just as they are to the output folder. All binary files makes sense to include here. To treat css differently we need another rule for that:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-ruby"&gt;compile '/**/*.css' do
  git_hash = `git rev-parse --short HEAD`.chop
  write "#{item.identifier.to_s[..-5]}.#{git_hash}.css"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thanks to ruby this can be done in this compact way. (Just imagining doing this in Javaish….) Ruby treats antything between bakticks as calls to the command line. &lt;code&gt;rev-parse --short&lt;/code&gt; is a nice way to get the hash of the current commit. And indexing with a range is perhaps not that readable but it is fun and here it is quite easy to understand what it does. Just chop off the 4 last characters of the incoming file name. Then add hasn and suffix and done deal.&lt;/p&gt;

&lt;p&gt;I thougt about putting the file name code in common code but since it was only two lines I decided against. The other place where a change was needed was of course the layout file where the css is used. In my setup here it is still in the default layout used by everything on the site. It is only &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; stuff in there now.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-haml"&gt; / style is style
 - css_path = "/stylesheet.#{`git rev-parse --short HEAD`.chop}.css"
 link rel="stylesheet" href="#{relative_path_to(css_path)}"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Using &lt;a href="https://slim-template.github.io/"&gt;slim&lt;/a&gt; (since it is nice to be able to look at code and not die). You’ll recognize the same code to generate the file name just inlined a bit differently. And then it is added as the stylesheet of the site. Quite neat!&lt;/p&gt;

</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2025-01-04:/2025/01/centrale-cocktail/</id>
    <title type="html">centrale</title>
    <published>2025-01-04T00:00:00Z</published>
    <updated>2025-01-04T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2025/01/centrale-cocktail/" type="text/html"/>
    <content type="html">&lt;p&gt;I got some coffee liqueur (Spresso) and started fiddling with a recipe containing that. After some iterations I found that bourbon (I have used bulleit) goes nice with the coffee bitterness. Also Cointreau balances up with some sweetness. Add to that some orange and lemon juice and it is a really tasty thing.&lt;/p&gt;

&lt;p&gt;Ingredients:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;3 parts bourbon&lt;/li&gt;
  &lt;li&gt;2 parts cointreau&lt;/li&gt;
  &lt;li&gt;1 part coffee liqueur&lt;/li&gt;
  &lt;li&gt;2 parts orange juice&lt;/li&gt;
  &lt;li&gt;1 part lemon juice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How to do it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;put ice in a shaker&lt;/li&gt;
  &lt;li&gt;add all the ingredients&lt;/li&gt;
  &lt;li&gt;shake for some time&lt;/li&gt;
  &lt;li&gt;pour into a coupe&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;p&gt;Then what do we call this new cocktail. I wanted to call it Stazione but it turns out there &lt;a href="https://www.diffordsguide.com/cocktails/recipe/4664/stazione"&gt;is a cocktail with that name&lt;/a&gt; already. A strega/fernet/vermouth combo that doesn’t sound that great to be honest. But I’ll try it - it has a good name. So instead I settled for Centrale which is alomst the same thing in italiano.&lt;/p&gt;

</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2024-12-13:/2024/12/kotlin-concurrency/</id>
    <title type="html">concurrency in kotlin</title>
    <published>2024-12-13T00:00:00Z</published>
    <updated>2024-12-13T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2024/12/kotlin-concurrency/" type="text/html"/>
    <content type="html">&lt;p&gt;&lt;strong&gt;Update in January 2025&lt;/strong&gt;: after using it for a while I realized that it is not that simple as outlined below. I added some notes in a &lt;a href="../../../2025/01/kotlin-concurrency-revisited"&gt;later post&lt;/a&gt; about those revelations.&lt;/p&gt;

&lt;p&gt;We tried out some concurrency coding in Kotlin this week in my team. We are building an android app with a backend (also in kotlin) that reaches out to several other micro services to get information. A new endpoint we built was quite slow (upwards 15 seconds to respond or so) in some cases so we decided to do something about it. As is best practice we hadn’t really built specifically for performance before but waited for contact with reality before optimizing for speed. Kotlin has a really nice library called &lt;a href="https://github.com/Kotlin/kotlinx.coroutines"&gt;kotlinx.coroutines&lt;/a&gt; that can be used for this purpose. Consideering how clumsy this is to do with Kotlins bigger brother Java it was a nice surprise to discover the possibilities here. From the languages I have worked with I hold Go as having best built-in support for concurrency but this is reallt on the same level. Lets look at some examples.&lt;/p&gt;

&lt;h3 id="calling-two-things-at-the-same-time"&gt;Calling two things at the same time&lt;/h3&gt;

&lt;p&gt;A common case for parallelism is when you need to get data from several independent services. The naive approach is - of course - to call one first and then the other. This is typically also the easiest code to read. Say you have a function to call some slow animals:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-kotlin"&gt;fun callSomeSlowAnimals(): CombinedAnimalResponse {
    val tortoiseAnswer = callTortoise()
    val slothAnswer = callSlot()
    return CombinedAnimalResponse(tortoiseAnswer, slotheAnswer)
}

fun callTortoise(): String = "Hello"
fun callSloth(): String = "Hi there"

// and the rest you can figure out....
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pretty straightforward. Now lets do these calls in parallell instead:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-kotlin"&gt;fun callSomeSlowAnimals(): CombinedAnimalResponse =
    runBlocking {
        val tortoiseAnswer = async { callTortoise() }
        val slothAnswer = async { callSloth() }
        CombinedAnimalResponse(tortoiseAnswer.await(), slotheAnswer.await())
    }
}

suspend fun callTortoise(): String = "Hello"
suspend fun callSloth(): String = "Hi there"

// and the rest you can figure out....
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see we have introduced 4 new building blocks here to make this happen. First there is the &lt;code&gt;runBlocking&lt;/code&gt; call that sets up a context where parallelism can happen. Calls to &lt;code&gt;async&lt;/code&gt; can only happen inside one of these.&lt;/p&gt;

&lt;p&gt;The we have async that accepts a block that you want to call asynchronously. It returns an object of the type &lt;code&gt;Defferred&lt;/code&gt;. This is much like a future or promise in some other language.&lt;/p&gt;

&lt;p&gt;Then to actually wait for the call to finish we need the &lt;code&gt;await()&lt;/code&gt; call to the &lt;code&gt;Deferred&lt;/code&gt; instances. The first one of these that is encountered will wait for a response. But other calls to async happens in the background so we will have two things going on.&lt;/p&gt;

&lt;p&gt;Finally the functions we call are marked with the keyword &lt;code&gt;suspend&lt;/code&gt;. This is needed to say that these are possible to call in an asynchronous manner. They are thread safe.&lt;/p&gt;

&lt;h3 id="calling-many-things-at-the-same-time"&gt;Calling many things at the same time&lt;/h3&gt;

&lt;p&gt;So this is all good but perhaps you want to call to all present tortoises at the same time. But you don’t really know how many these are. In comes channels that can be used to kinda save asynchronous answers while moving on to new calls. Say you have a function that calls a bunch of tortoises one after the other:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-kotlin"&gt;fun callACoupleOfTortoises(): List&amp;lt;String&amp;gt; =
    repeat(5) { callTortoise() }

fun callTortoise(): String = "Hello"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Lets do this with channels and coroutines instead:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-kotlin"&gt;fun callACoupleOfTortoises(): List&amp;lt;String&amp;gt; {
    val answers = mutableListOf&amp;lt;String&amp;gt;()
    runBlocking {
        val ch = Channel&amp;lt;String&amp;gt;(5)
        repeat(5) { launch { ch.send( callTortoise() ) } }
        ch.close()
        repeat(5) { answers.add( ch.receive() ) }
    }
    return answers
}

suspend fun callTortoise(): String = "Hello"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So this is a bit messier but still quite clean. We have the &lt;code&gt;runBlocking&lt;/code&gt; thing to tell kotlin that we are gonna to async stuff. Then we create a channel for strings. We now it’s gonna be of 5 capacity at this point but it can be dynamic as well. We use &lt;code&gt;launch&lt;/code&gt; to do things asynchronous. This is not a promise but rather a job. Then we send the response from our tortoise to the channel. The stuff inside the launch happens in parallell. When we have sent all the things we close the channel and move on to receieving results from the channel. And the function needs to be suspended. Pretty straightforward.&lt;/p&gt;

</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2024-11-21:/2024/11/ivrea-painting/</id>
    <title type="html">a photo painting of Ivrea</title>
    <published>2024-11-21T00:00:00Z</published>
    <updated>2024-11-21T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2024/11/ivrea-painting/" type="text/html"/>
    <content type="html">&lt;p&gt;Sometimes a photo becomes a painting as happened the first morning in Ivrea. The morning mist was fighting the rising sun.&lt;/p&gt;

&lt;p&gt;&lt;img src="../ivreapainting.jpg" alt="sun is rising over ivrea and its river" /&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2024-11-09:/2024/11/sfscon24/</id>
    <title type="html">sfscon24</title>
    <published>2024-11-09T00:00:00Z</published>
    <updated>2024-11-09T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2024/11/sfscon24/" type="text/html"/>
    <content type="html">&lt;p&gt;&lt;a href="https://www.sfscon.it/"&gt;SFSCON&lt;/a&gt; has not been on my radar. Not that I can remember at least. When I switched jobs I started looking at the open source conference offerings in Europe and stumbled over it. I visited Bolzano in February 2022. (On the trip causing &lt;a href="/2022/05/italy-22-trip/"&gt;these photos&lt;/a&gt;.) As I do I went with train from Stockholm so had to start in the early morning two days before the confernece. It was nice to arrive the evening before in Bolzano to settle in and experience a bit of this nice town in the dolomites.&lt;/p&gt;

&lt;p&gt;The conference may be the second biggest in Europe around open source with 1000 attending. After fosdem then… It started out with a couple of single track talks in the biggest room and then it was a four track conference after that with a couple of different teams. Naturally I spent most of the time in the developers track given that is what I am. The first day - friday - is really packed with talks. And then it is a more easy going Saturday ending before lunch. In parallel there is also a hackathon. I was not up for that this time. I know it can be quite intense and coding with a laptop in a sofa is not something my body particularly appreciates these days.&lt;/p&gt;

&lt;p&gt;The conference is free. Still lunch and coffee ws included. That was a nice surprise. I had a really nice melanzane. The venue - NOI Techpark - is a couple of kilometers southwest of the centre of Bolzano. It is possible to go there by train to Bozen Sud or by bus. I walked which took me some 40 minutes. The most direct route is through mostly industrial areas but cross the river and you can walk through residential areas instead.&lt;/p&gt;

&lt;p&gt;&lt;img src="../sfscon-sharepic.jpg" alt="A kind of badge showing sfscon stuff, my name and the mazin logo - the bird" /&gt;&lt;/p&gt;

&lt;p&gt;The opening session was nice in that it set the context of the conference. Especially for a newcomer like myself.&lt;/p&gt;

&lt;p&gt;The first real talk I attended was &lt;a href="https://www.sfscon.it/talks/open-source-businesses-as-an-independent-sustainable-way-to-fund-open-source/"&gt;Open Source Businesses as an Independent, Sustainable way to Fund Open Source&lt;/a&gt; by &lt;a href="https://www.emilyomier.com/"&gt;Emily Omier&lt;/a&gt;. It was a nice walkthrough of the different options there are for making a living out of open source software.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Open source is free to use but it is not free to create&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The commonly used tip jar model was not Emiliy was impressed by. Look for other business models to create a sustainable company around the open source software.&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://www.sfscon.it/talks/almalinux-in-brief/"&gt;nice introduction&lt;/a&gt; to &lt;a href="https://almalinux.org/"&gt;AlmaLinux&lt;/a&gt; by benny Vasquez. I’m on Fedora as I am writing this but still dodn’t know about this new CentOS replacement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.sfscon.it/talks/apisense-easily-monitor-and-track-your-rest-api-data-quality/"&gt;Apisense - Easily monitor and track your REST-API data quality&lt;/a&gt; was a talk by two quite new developers about a tool to monitor rest APIs. I can see some use cases for this kind of software. It seemed they were mostly using it for sensors and stuff like that and that may make sense. But if you control the data flow it should be quite easy to just verify data quality in the &lt;em&gt;normal&lt;/em&gt; code instead. I can see a use case when consuming third party APIs. Especially when it comes to anomaly detection. if an API starts to behave differently than it normally does without failing completely that would be interesting to monitor. Partial data loss for example or values out of normal bounds.&lt;/p&gt;

&lt;p&gt;Many talks touched on the AI hype. Fulvio Mastrogianni had an interesting talk called &lt;a href="https://www.sfscon.it/talks/on-the-ethical-challenges-raised-by-robots-powered-by-artificial-intelligence/"&gt;On the ethical challenges raised by robots powered by Artificial Intelligence&lt;/a&gt; where he went through the current state of having robots with some kind of intelligence. He pointed out that humans normally have an observe-think-act pattern but that the current hyped AIs are not doing any thinking yet. So they can produce mechanical answers that appears to be intelligent but can not really connect the dots. So it is not likely that the LLMs will extend out in the physical world anytime soon.&lt;/p&gt;

&lt;p&gt;A rather practical one around AI was &lt;a href="https://www.sfscon.it/talks/mariadb-vector-why-your-ai-data-should-be-in-an-rdbms/"&gt;MariaDB Vector: Why your AI data should be in an RDBMS&lt;/a&gt; by Kaj Arnö describing new AI features of MariaDB. Very interesting and also outlining a use case based on own data rather than the crowd sourced AIs we see mostly out in the wild.&lt;/p&gt;

&lt;p&gt;Linters are kinda dull aren’t they. We have one now where I work for kotlin and it just pops out a bit after the fact complaining about a comma and such. Eduardo Guerra has solved it with emojis. In &lt;a href="https://www.sfscon.it/talks/codeemoji-making-code-more-informative-with-emojis/"&gt;codEEmoji – Making code more informative with emojis&lt;/a&gt; he told us how. 🐘 marking too long functions, 🤷 for bad names and so on. I think I will try it. It is &lt;a href="https://plugins.jetbrains.com/plugin/22416-codeemoji"&gt;only for IntelliJ&lt;/a&gt; at the moment but may make it into VSCode as well eventually.&lt;/p&gt;

&lt;p&gt;Then another AI talk. (To be honest I have AI fatigue.) This one quuestioning &lt;a href="https://www.sfscon.it/talks/can-test-driven-development-be-speeded-up-with-generative-ai/"&gt;Can Test Driven Development be speeded up with Generative AI?&lt;/a&gt;. Jorge Melegati argued that it is possible. I’m quite sceptical about these things. If we let AI (meaning LLM) write code for us we will need to spend as much time reviwing it. I guess the future will tell if this was something to keep or not. I will continue to write my code myself in the meantime.&lt;/p&gt;

&lt;p&gt;After this talk I went for a walk. When I came back I tried to listen to &lt;a href="https://www.sfscon.it/talks/the-innovation-paradox/"&gt;The Innovation Paradox&lt;/a&gt; but I don’t remember much. I think it was good stuff though.&lt;/p&gt;

&lt;p&gt;Then onto the problem of slicing elephants with a talk called &lt;a href="https://www.sfscon.it/talks/monolith-splitter/"&gt;Monlith Splitter&lt;/a&gt;. Here we had some software that could analyze a monolith based on execution paths and git logs to come with a suggestion for how to break it up into micro services. I still don’t get how the git logs comes into the picture. Potentially you could understand what parts of the code changes at the same time or something. But to me it feels like it is quite secondary information compared with execution paths. Still an intersting problem. I am in a team that are replacing a PHP monolith. I’m not sure an approach like this would have helped us much since we (and other teams) are rewriting the thing in Kotlin and Java. In some cases we have to understand the old logic on a deeper level than just execution paths and in many other cases we can just build a better replacement without thinking too much about it. The business side of things are crucial to understand when it is important to dig into the old monolith and when we can just continue running.&lt;/p&gt;

&lt;p&gt;And yet another AI talk called &lt;a href="https://www.sfscon.it/talks/from-personalized-to-programmed/"&gt;From Personalized to Programmed&lt;/a&gt; where Thomas Aichner put forward a few use cases where AI is not really working. No surprise there but an entertaining talk.&lt;/p&gt;

&lt;p&gt;Ivar Grimstad of the Eclipse Foundation had a talk called &lt;a href="https://www.sfscon.it/talks/nurturing-openjdk-distribution-eclipse-temurin-success-history-and-plan/"&gt;Nurturing OpenJDK distribution: Eclipse Temurin Success History and plan&lt;/a&gt;. The main getaway for me is that Temurin is an anagram….&lt;/p&gt;

&lt;p&gt;Then a really interesting talk about &lt;a href="https://www.sfscon.it/talks/designing-open-source-tools-for-citizen-coders/"&gt;Designing open source tools for Citizen Coders&lt;/a&gt;. Luca Rainone rightly argued that it can be hard for non-developers to contribute. People of other professions may want to do things in an open source project but the hrudles may be too high. Making it lower would be beneficial for all. The code wil be easier to maintain and evryone can get started more easily.&lt;/p&gt;

&lt;p&gt;The last day was a bit sparse on content and I also had a train to catch. I arrived in time for the workshop &lt;a href="https://www.sfscon.it/workshops/knitting-our-internet/"&gt;Knitting Our Internt&lt;/a&gt; hosted by &lt;a href="https://pan.rent/@tommi"&gt;Tommaso Marmo&lt;/a&gt;. It was a stroll through the history of the internet. I kinda suspected that I knew all of this already which turned out to be true. But it was inspring to experience in person nevertheless. I’m old enough to have lived through the commercialization of the internet and it is something that makes me sad. The main point from the workshop was to use yarn to demonstrate the difference between a centralized social network and a decentralized one. Whenvever there is a central node that everything goes through that node can control what content arrives with which user. It is - perhaps obivious - ironic that the internet was designed to be decentralized but is now used mostly for centralized things. I havwe been thinking about writing something about this for some time and maybe the time has come!&lt;/p&gt;

&lt;p&gt;The last talk was an introductory to the fediverse by Tobias Diekershoff one of the developers of friendica. Nothing new here really but a good introduction and I hope some more people got inspired to make the move. And as Tobias pointed out - it is still possible to be on commercial platforms and give away data in exchange for ads.&lt;/p&gt;

&lt;p&gt;To sum up this was a really nice confernce. Not as huge an chaotic as &lt;a href="https://fosdem.org/2025/"&gt;fosdem&lt;/a&gt; but leacing it with the same kind of warm feeling. This is my people and we’ll make the world a bit better each day. Actually my next conference will probably be fosdem in early February. See you there perhaps?&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2024-11-06:/2024/11/6-months-of-kotlin/</id>
    <title type="html">6 months of kotlin</title>
    <published>2024-11-06T00:00:00Z</published>
    <updated>2024-11-06T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2024/11/6-months-of-kotlin/" type="text/html"/>
    <content type="html">&lt;p&gt;&lt;img src="../kotlin-logo.svg" alt="kotlin logo" /&gt;&lt;/p&gt;

&lt;p&gt;I have now worked with &lt;a href="https://kotlinlang.org/"&gt;kotlin&lt;/a&gt; for a bit more than half a year and thought it was about time to write down some insights. So far I have worked profesionally with Java, JavaScript, Ruby, Go, Groovy, Elm and Python to give you some context of my previoous experiences. I have worked quite a lot in tha Java space so that is what I know most about. My last job howver was with Python mostly so it actually been 5 years since I touched the JVM last. My experience now is from backend work built with spring and serving an android app.&lt;/p&gt;

&lt;h3 id="main-takeaways"&gt;Main takeaways&lt;/h3&gt;

&lt;p&gt;Kotlin is a better Java. It invites to functional style although all the OO legacy of Java is still around. Many Kotlin features are slowly making their way into Java. It’s a feeder team for Java.&lt;/p&gt;

&lt;p&gt;Kotlin runs on the JVM. The pros of this are obviously access to the vast ecosystem of Java. Using a framework like Spring boot is easy and comes with almost no hassle. The cons are just as obviously. The Java ecosystem is quite bloated and turnaround times for feedback loops are typically quite slow.&lt;/p&gt;

&lt;h3 id="my-top-five-features"&gt;My top five features&lt;/h3&gt;

&lt;h4 id="functions-on-one-line"&gt;Functions on one line.&lt;/h4&gt;

&lt;p&gt;It is possible to define a function without curly braces but then it needs to be one statement. If it is short enough it fits on one line.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-kotlin"&gt;fun square(Int: x): Int = x * x
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is nice. The downside is that you can spread your statement over several lines and do some function chaining to avoid the curly braces. This seems to be idiomatic in Kotlin but is sometimes not that readable. (Easy to fix though with a bunch of shorter functions.)&lt;/p&gt;

&lt;h4 id="parallelism"&gt;Parallelism&lt;/h4&gt;

&lt;p&gt;We haven’t used it yet in the code base I hang out in now. But it looks really neat as compared to this in Java. There are all kinds of async possibilities and also channels in Go style. So now you can do something like:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-kotlin"&gt;fun squareManyNumber(List&amp;lt;Int&amp;gt; numberList): List&amp;lt;Int&amp;gt; {
    val squareChannel = Channel&amp;lt;Int&amp;gt;()
    launch {
        numberList.forEach {
            channel.send(square(it))
        }
    }
    val resultList = mutablieListOf&amp;lt;Int&amp;gt;()
    repeat(numberList.size()) { resultList.add(squareChannel.receive()) }
    return resultList
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id="it"&gt;It&lt;/h4&gt;

&lt;p&gt;This is the default name for parameters into blocks. The first time you see it it is kind of weird. But then you get used to it and it is convenient in some code. And for multi line blocks it is often wise to use a parameter name instead. But as always it depends. You can see it being used above.&lt;/p&gt;

&lt;h4 id="nested-functions"&gt;Nested functions&lt;/h4&gt;

&lt;p&gt;It is possible to declare functions inside a function local to that scope. This can be really convenient when you have lots of parameters and don’t want another parameter list. It is a bit like &lt;code&gt;let&lt;/code&gt; in other languages. Silly exmple below:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-kotlin"&gt;fun square(x: Int): Int {
    fun internalSquare(): Int = x * x
    
    return internalSquare()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id="extension-functions"&gt;Extension functions&lt;/h4&gt;

&lt;p&gt;Sometimes called monkey patching. It is possible to add functions to any class which makes it much easier to write readable code but can cause confusion at times. We use it both for standard library classes and our own classes. Lets add square to the Int class as an example:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-kotlin"&gt;fun Int.square(): Int = this * this
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yep quite intuitive right?&lt;/p&gt;

&lt;h3 id="things-i-dont-like"&gt;Things I don’t like&lt;/h3&gt;

&lt;h4 id="typed-functions"&gt;Typed functions&lt;/h4&gt;

&lt;p&gt;Well this is a language with static types so you natrually have to type things all over the place. Type inference works as it should so it is just as much as necessary. But consider a function that returns another function. Sometimes I like to generate small functions. Here the type of that function is so hard to parse that it is almost never worth the effort. Too much noise and better solved in some other way.&lt;/p&gt;

&lt;h4 id="linter"&gt;Linter&lt;/h4&gt;

&lt;p&gt;Well I Really like that there is a common idea on what the code should look like. I just don’t like what that is. But better that all code is formatted in the same way then it can vary inside a code base. For me the linter is much too aggressive with line breaks. Whenever you have a multi line function call it will need a line break for each part of the signature. I don’t mind named parameters and multi line calls at times but sometimes I just want something compact instead. It depends on the context.&lt;/p&gt;

&lt;h3 id="summing-it-up"&gt;Summing it up&lt;/h3&gt;

&lt;p&gt;There are quite a few more things I don’t like but overall there is much to like with the language. It is a much nicer developer experience as compared with Java. Personally I prefer dynamic like languages like Python or Ruby. They help me write the most readable code that can also be beautiful. With types there is some more noise that gets in the way. For code bases that will likely see many developers over the years I believe that there is no point avoiding static typing. The few bigger dynamically typed systems I have seen has been really hard to maintain. It takes some testing to keep them stable and maintainable. And testing is not something every developer will do. Most develoeprs that do test does it after the fact so it is likely that parts of the code does not have that code test coverage. Kotlin comes as far as is possible to be light weight while still have the rigouorsness of static types.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2024-08-25:/2024/08/key-indicators/</id>
    <title type="html">key indicators for software development</title>
    <published>2024-08-25T00:00:00Z</published>
    <updated>2024-08-25T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2024/08/key-indicators/" type="text/html"/>
    <content type="html">&lt;p&gt;So over the years I have developed two “important” key indicators to measure how well
an organization developing software is doing. They are both ratios between things and there are no The correct.&lt;/p&gt;

&lt;h3 id="the-dee-indicator"&gt;The D/EE indicator&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;Ratio of number of developers to everyone else&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first one came quite some time ago when someone noted that developers were not even half the folks
in the software development part of the company I worked at then. So this is the 
ratio between people coding and other people in the organization. After all - coding is where stuff actually happens. Everyone 
else has a supporting role.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Everyone else&lt;/em&gt; comes in many shapes and here are som examples:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;managers of line, project or product variety&lt;/li&gt;
  &lt;li&gt;product owners and other product roles previously known as requirements something&lt;/li&gt;
  &lt;li&gt;user interface/experience/design and such&lt;/li&gt;
  &lt;li&gt;testers and test managers, QA and such&lt;/li&gt;
  &lt;li&gt;devops engineers perhaps or sysadmins as they were used to be called&lt;/li&gt;
  &lt;li&gt;coaches and agile specialist&lt;/li&gt;
  &lt;li&gt;change control people&lt;/li&gt;
  &lt;li&gt;security specialists&lt;/li&gt;
  &lt;li&gt;DBA&lt;/li&gt;
  &lt;li&gt;Jira configurators&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yep the list can be made longer than this as well. They are just examples for what kind of “other” roles there can be.
And I would only consider roles actually working with software development. Depending on the type of business we have
there will be more people around.&lt;/p&gt;

&lt;p&gt;So what is a healthy ratio here? I would say that if less than half are developers there is most likely a severe overhead
problem in the organization. It will also be likely that the developing teams has less freedom over their work then what
is desirable. On the other hand if almost all are developers there are probably things that are not going that
well. Like design or figuring out new product paths and such. Or security. This may be fine in a small organization but 
as it grows, non developing specialist roles are surely needed. Figure out what strengths the organization have and strenghten
the ones where there is a deficit.&lt;/p&gt;

&lt;h3 id="the-pw-indicator"&gt;The P/W indicator&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;Ratio of time spent doing planning as compared to actually working on the plan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Planning is inventory. This is well known. And some inventory may be needed in order to be able to work as a group of collaborating people.
So from the point planning starts, until it is actually either discarded (and erased from everyones brain) or implemented in code
or with some other measure, planning is a kind of debt. We invest time in planning in the hope that it will be converted into
deployment and business value further on. As you may guess I often feel that we do too much planning. Many times the same improvement is planned
over and over again before it is actually done. If the time spent planning actually exceeds the time doing it we can try two times without 
plans for the same cost. This is why we mostly work with increments these days. As small as possible. But in larger organizations
there are planning for the next quarter and sometimes even further than that. This may be necessary to be able to communicate with
stakeholders and internally in an organization.&lt;/p&gt;

&lt;p&gt;With that said I introduce the ratio between time spent planning and time spent working as an important ratio. Where I work now the ratio 
is somewhere between 5 to 15 % in planning. This is healthy but I am sure it can be pushed to even less than that. It is something that has to be learned
in every group. So what are factors that enables a lower degree of planning:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;an organization based on trust is crucial&lt;/li&gt;
  &lt;li&gt;planning happens where it will be implemented. All other planning should be extremely high level and not be expensive at all.&lt;/li&gt;
  &lt;li&gt;business specialists available in the organization and present when the planning happens&lt;/li&gt;
  &lt;li&gt;don’t keep backlogs and especially do not go through them over and over again&lt;/li&gt;
  &lt;li&gt;the right time to do detailed planning is just before implementation or even during it&lt;/li&gt;
  &lt;li&gt;the longer it takes between planning and doing, the more likely it is that the planning will need to happen again&lt;/li&gt;
  &lt;li&gt;no one is held accountible to the plan - if someone needs to deliver on the plan there will surely be more planning&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id="connecting-the-dots"&gt;Connecting the dots&lt;/h3&gt;

&lt;p&gt;As you can see these two indicators relate a lot to each other. But as D/EE counts heads, P/W counts time. Also not everyone in the 
&lt;em&gt;everyone else&lt;/em&gt; block is doing planning. Some are doing other things. Like assuring quality or taking a stand on security. And natrually also
developers do a lot of planning. Nevertheless it is likely that an organization with a low D/EE indicator willl also have a high P/W.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2024-07-14:/2024/07/norpan/</id>
    <title type="html">norpan</title>
    <published>2024-07-14T00:00:00Z</published>
    <updated>2024-07-14T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2024/07/norpan/" type="text/html"/>
    <content type="html">&lt;p&gt;A trip to Norrköping is coming up so it is reasonable to create a drink for the occasion.
Norrköping is &lt;em&gt;Norpan&lt;/em&gt; in slang so that will be the name. A former industrial power house 
needs something heavy on tha alcohol and some trocadero on top of that. Here is the recipe:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Put some ice in a bowl or something.&lt;/li&gt;
  &lt;li&gt;Add equal amounts of bourbon, vodka and cointreau.&lt;/li&gt;
  &lt;li&gt;Stir&lt;/li&gt;
  &lt;li&gt;Pour (without ice) into a common type of glass.&lt;/li&gt;
  &lt;li&gt;Add en equal amount of Trocadero and there you go.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some may find Norpan a bit strong. If that is the case add two more equal amounts of Trocadero for
 a &lt;em&gt;Norpan Half Barrel&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src="../norpan.jpg" alt="the norpan drink" /&gt;&lt;/p&gt;

</content>
  </entry>
  <entry>
    <id>tag:mazin.cc,2024-07-13:/2024/07/🗺/</id>
    <title type="html">🗺</title>
    <published>2024-07-13T00:00:00Z</published>
    <updated>2024-07-13T00:00:00Z</updated>
    <author>
      <name>fredrik</name>
      <uri>https://mazin.cc</uri>
    </author>
    <link rel="alternate" href="https://mazin.cc/2024/07/🗺/" type="text/html"/>
    <content type="html">&lt;p&gt;Special unicode characters are a pretty cool thing and used too seldom methinks. I decided to suffix titles of this
&lt;a href="/weblog"&gt;weblog&lt;/a&gt; with some unicode glyphs representing the content. So far there is 📷 for photo posts, 🚆 for 
itineraries and as of today 🗺 for posts with maps at the bottom. This map symbol is part of the 
&lt;a href="https://en.wikipedia.org/wiki/Miscellaneous_Symbols_and_Pictographs"&gt;Miscellaneous Symbols and Pictographs&lt;/a&gt; unicode block.
It is also interesting to see how a wide glyph like this fares in a URL and we’ll find out just now.&lt;/p&gt;
</content>
  </entry>
</feed>

