It’s been a while since I did one of these. luna-puella asked me these questions:

1. You have picked up a lot of hobbies over the years. Which was your favourite?
I will have to go with tabletop RPGs here, because it’s the most long-lived and thus seems to be the best fit for me. I have been playing ttrpgs for 35 years now, and there are no signs of slowing down. My tastes have changed (a lot!) but that’s what keeps it fresh.

2. What do you think is the keyIf behind a successful marriage?
Ultimately, I think it is respect. It is in the many, very mundane, ways you can make your partner’s life better by cooperating with them. What that looks like depends on you, but for us it’s doing our share of chores, working around (or with!) our respective neuroses and supporting each other.
Of course, love is a prerequisite — but respect makes marriages last.

3. What’s your pet peeve in the design of social media sites?
I was going to protest that I haven’t really used all that many social media sites, but then I realized that I have been using systems that would be considered social media today, even before the term ‘social media’ existed…
If we’re talking about interface design, then my requirements are simple: I want the content I am interested in, delivered in a constant stream. So I want smooth scrolling by keyboard, something that the web interface of Mastodon has a bit of trouble with, for instance. If you interact with a toot (favouriting or boosting, for instance), then that toot is ‘selected’ and the arrow down selects the next one. Which is fine, but on my little 10″ laptop not every toot fits on the screen in one go, and it is annoying to have to click outside of the list of toots in order to be able to scroll with the arrow keys again.
If we’re talking about the algorithmic design (which content the site is delivering), then I think it is safe to say that corporate-owned social media is a blight upon mankind and must be completely eradicated. It was a very bad idea to leave our public discourse in the hands of a privately-owned company.

4. If you were absolute king for a day (not encumbered by democratic legislative processes), what law would you push through?
Universal Basic Income. I can’t think of a single thing that would improve the lives of… basically everyone more than UBI.
Maybe a 100% tax on anything over 1 billion (or maybe even 100 million) could be a part of that? There’s enough money, it’s just not distributed in a way that maximizes its effects.

5. If you could pass on one recommendation (book, movie, life lesson), what would it be?
World Peace Is Possible.
There’s nothing magical about world peace: if everyone stopped fighting, we could achieve world peace within an hour! The trick is, then, to create the circumstances in which people do not fight, and everyone, every day, can make choices that bring us closer to world peace. But for that to happen, people need to realise that world peace is achievable and desirable — and now you know, so now you can start making those choices.
(Example: I work in Enterprise Content Management, in order to bring world peace closer. Because things like agreements and contracts are written down and stored in ECM systems, and having that information available and trackable reduces the number of conflicts people have about whatever was agreed upon — thereby reducing the number of reasons for people to fight. Is it a stretch? Perhaps. But it’s true, if you think about it. And everyone can make choices like that, every day.)

Thank you for the thoughtful questions, luna-puella! And if any of you want to play too, comment and I’ll give you five questions to answer!

So I said I was probably not going to do the other days of Advent of Code, but it’s just too much fun, and I’m re-learning some fun Prolog tricks. And some of the assignments are of the type “find (or count) all occurrences where X is true”, and Prolog is ideally suited for that! I solved the assignment for day 2 in basically ten lines of code: nine for a scoring table and one line to do the actual work!

The assignment for day 3 required string manipulation, which is not something Prolog is very good at — it is one of the reasons it’s not a language to Get Stuff Done, because input or output manipulation is a large part of any kind of serious software development. So my solution is kinda kludgy, but the bonus is that it is robust against multiple types of equipment being packed double!

The day 4 assignment is, once again, a “find all X for which Y is true” and that is what Prolog does. So the solution is, once again, very concise: two lines of code to set the requirements, one line of code to find all items that satisfy those requirements.

I’ve switched to using pastebin for the code, because most of you will probably not care and my blog is not suited for posting code anyway. And I have a busy week ahead of me, so it might be that this is as far as I go with it.

Advent of Code in Prolog

The Advent of Code is a yearly recurring event in which puzzles are given which the players must solve with a computer program. It reminds me of the ACM Scholastic Programming Contest, but there is no ‘run environment’ and no judge. There is a leaderboard I think, but I’m not bothering with that — it’s a fun puzzle activity, not much more for me.

The first puzzle can be found on the AoC website, and I thought it would be fun to solve the problem in Prolog. Prolog remains my favourite for its expressiveness and the way it takes care of all kinds of mundane bookkeeping. In Prolog, you express what is true, and leave it to the machine to solve a question based on that — each Prolog program is like a zen koan. It is not the language to Get Shit Done, that’s mostly PHP, Java and C# these days. But you just can’t beat Prolog as an expression of beauty and truth.

So a little puzzle? That is very well suited for using Prolog! It’s been a (long) while since I programmed in Prolog, and I had to look up the exact syntax of a few of the built-in predicates, but I am pretty pleased with the result! Code under the cut.

Here’s my code (with the comments bolded for readability — my blog style is not really suited for sharing source code):
% This is our database with facts.
snack(elf1, 1000).
snack(elf1, 2000).
snack(elf1, 3000).

snack(elf2, 4000).

snack(elf3, 5000).
snack(elf3, 6000).

snack(elf4, 7000).
snack(elf4, 8000).
snack(elf4, 9000).

snack(elf5, 10000).

% An elf is in the expedition if it carries at least one snack.
elf_in_expedition(Elf) :- snack(Elf, _).

% The list of elves is the set of elves in the expedition.
elflist(ElfList) :- setof(Elf, elf_in_expedition(Elf), ElfList).

% sum_calories/2 takes a list as input and sums the numbers in the list and returns that as the second argument.
% Sum of an empty list is 0.

sum_calories([], 0).
% The sum of a list is the sum of the rest of the list plus the head of the list.
sum_calories([X|Rest], Result) :- sum_calories(Rest, RestResult), Result is X + RestResult.

% To find the total number of calories an elf is carrying, make a list of the calories of all the snacks the elf is carrying, and calculate the sum of that list.
total_calories(Elf, TotalCalories) :- findall(Calories, snack(Elf, Calories), CalorieList), sum_calories(CalorieList, TotalCalories).

% max_calories/2 returns the elf who is carrying the most calories and how much calories it is carrying. To do so, it first constructs the list of elves with snacks and calls max_calories/3.

max_calories(Elf, MaxCalories) :- elflist(ElfList), max_calories(Elf, MaxCalories, ElfList).

% If there are no elves in the list, then the total number of calories is 0 and there is ‘no elf’.
max_calories(no_elf, 0, []).
% The elf at the head of the list is the elf carrying the most calories if the total calories it is carrying is higher than the number of calories the elf with the highest number of calories in the rest of the list is carrying.
max_calories(Elf, ElfCalories, [Elf|RestElves]) :- total_calories(Elf, ElfCalories), max_calories(_, RestMaxCalories, RestElves), ElfCalories > RestMaxCalories.
% If the number of calories the elf at the head of the list is carrying, is lower (or equal) to the number of calories the elf with the highest number of calories in the rest of the list is carrying, then that elf is the elf with the highest number of calories in this list.
max_calories(RestMaxElf, RestMaxCalories, [Elf|RestElves]) :- total_calories(Elf, ElfCalories), max_calories(RestMaxElf, RestMaxCalories, RestElves), ElfCalories =< RestMaxCalories. Running this with the fee GNU Prolog interpreter yields the result:

| ?- max_calories(Elf, MaxCalories).

Elf = elf4
MaxCalories = 24000

That was a fun thing to do in an evening. Will I do others? Probably not.

It’s actually more like 1,5 weeks by now. Once the instance was there, setting up was not that hard — create an account, promote it to admin, set options through the web interface, and that’s that. Biggest problem for me was to create images to use as the header for my instance.
I do not want an open account policy: the current server is dimensioned for 10 accounts, and since I am responsible for what happens on the instance, I don’t want every rando on my server. But by and large, people I know and trust have chosen to set up an account on my instance — we’re now up to eight accounts.
It’s all working fine, but the day-to-day administrative tasks are more than I had anticipated. I have to approve ‘trending hashtags’, and that’s a constant stream. There is a suggested blocklist and I spent an evening setting that all up — because we don’t want anything to do with nazis and other denizens of “radical free speech zones”.

On some large servers, there have been incidents of people from minorities being moderated for speaking their truth. I got into some disappointing interactions while trying to explain how the network works to people who insisted that the whole of Mastodon is racist, and I put the offending server on a limited federation regime. It’s since been cleared up, but it’s a bit much to have to keep on top of — I do not envy the admins of the large open instances.
In response to all this, I have added a server rule that we prioritize the safety of marginalized people over the comfort of privileged people.
Two of ‘my’ users each donated a month of hosting costs, which I greatly appreciate.

Every so often, there is talk of (open) instances incorporating or turning into a foundation of sorts — that’s something I’d be interested in too, but at the same time I am hesitant to grow the instance because then it would get beyond my span of control.
So far, so good. We’ll see where it takes us.

If you still thought that Musk was a smart man, then the real-time collapse of Twitter should cure you of that misconception. It is, in some way, impressive how little he understands of what makes Twitter unique and how he dismantles the value it had through all kinds of hare-brained schemes.
But to those of us who were with LiveJournal back when it was sold to the Russians, it’s a bit of deja-vu — a platform that is so important to you is changing in a way that does not align with your own goals for it. That means you will have to make a choice, and in the case of LJ, my choice was to create my own blog and cross-post to LJ. (And earlier this year, I decided to start cross-posting to DW instead of LJ.)

I use Twitter much more than I use my blog — microblogging has a different energy. And I don’t have that much interaction on my blog as I do on Twitter. So yes, I am invested in Twitter as a platform. Its breakdown and the way Musk is treating the company and the employees, does not fill me with great optimism for the long-term survival of Twitter.
One alternative is Mastodon, an open-source federated microblogging system. Through the federation, instances exchange content and users can follow and communicate cross-instance. (The cool thing is that it’s also possible to block federation with specific instances, so you can keep the fascists out.)
But for me it is not feasible to run my own instance of Mastodon on my existing hosting like I do with WordPress for my blog. The Mastodon technology stack is much more complex, and there is no easy install option — so I would have to set up everything and, more importantly, keep everything up to date. That’s not something I am equipped and/or prepared to do.

But the cool thing is that there are several places that offer managed hosting for Mastodon. So I got together with a few people and decided that we would set up an instance and see how that goes. We would use it, and we could also offer accounts to those who are not able to host their own instances. Ideally, I would transfer ownership to a foundation of sorts that would ensure a thriving community and ensure the longevity of the system — but for now we go with the ‘benevolent dictator’ model.
I’m now waiting for my application to be approved and the instance to be, eh, instantiated. Can’t wait!

1. Do you like spicy food?
I like “white people spicy.” I can eat spicier than that, but then all I taste is the heat, and not the flavour of the food itself. Whenever I eat somewhere new, I need to find out whether the spicy-ness markings on the menu are calibrated to white people or to brown people… I tend to go for something explicitly mild when I’m not sure.

2. Do you like your cereal crunchy or soggy?
With at least some crunch left, but not overly hard.

3. Do you like ice in your drinks?
In soft drinks, I don’t care that much. I do like ice when drinking something distilled.

4. What is the strangest thing you have eaten?
Probably turtle. We had turtle hot pot in Yufuin, in Japan. It wasn’t bad, but not something I will seek out again. The turtle blood mixed with alcohol was weird, and I didn’t really like the turtle eggs that we got as a side dish.

5. What food would you like to eat right this minute?
Okonomiyaki. And, good news for me: Klik is baking okonomiyaki for dinner right now!

Texel vacation

A few weeks ago, we took our (now traditional) Texel vacation. We had booked a bit earlier in the season (in hopes of getting better/good weather) and we had a bigger chalet than previous years — mostly because my mother-in-law (who insists to pay for it) wanted to have a bigger shower. She and my sister-in-law go one week before us, so they stay there two weeks and we join them for the last week.
The ferry service to Texel has two boats. It takes about 20 minutes to cross, and with 5 minutes loading and unloading, they can manage to make a full round-trip every hour. So on busy days, when they use both, there is a ship leaving either end every 30 minutes. However, the largest of the two had engine trouble, so it was not in service — which meant a vastly reduced capacity, on one of the busiest days. Which meant it took us about four hours to get to the other side.
Us in the car, giving a thumbs up to the camera
We tried to keep our spirits up, but that got harder as it took longer and longer. We were so, so tired when we arrived — luckily our beds had already been made and dinner was ready for us!

Things did not go well for long, as my sister-in-law tested positive for COVID-19. She was coughing a lot, but did not suffer a lot of other symptoms, which was lucky. But it did restrict our activities a bit. We compensated by getting take-out from a few restaurants, and we decided we actually kinda liked it: good food and it’s more relaxed than sitting in a restaurant the whole evening. (We kept doing self-tests all through the week, but all of ours came up negative, too.)

Ever since we went to Texel, we tried to get a ride on a horse-drawn carriage that would go to the Slufter, a nature preserve where the sea is allowed to come through a gap in the dunes, creating tidal flats. But we never got around it: either it was full, or it was raining too hard, or there were too few participants… But this year we managed (though my sister-in-law could not join us…)
Two Belgian draft horses in front of a carriage at a bus stop
We went to the designated bus stop and there it was!
A view to the front of the carriage. Klik is on the left on the bench directly in front, her mother to the right
We were seated towards the front of the carriage. Klik and her mother were on the second bench from the front, I was right behind them. It was kinda rainy and windy, so the plastic covers had been zipped up. That limited the view to the side, so it was good we could look out the front. The driver talked a lot and pointed out all kinds of interesting stuff along the way, which was very entertaining.
The carriage parked on the beach at the Slufter
The route took us to the Slufter, and because the tide had been especially high, the horses had to draw the carriage partially through the water. At the edge of the beach, the carriage was parked and we got tea and coffee. We were free to look around and stretch our legs for a bit, but of course we couldn’t do any serious exploring.
Two Belgian draft horses in front of a carriage
Those Belgian draft horses are big. On the left is Nel, who is a bit younger and who needed a bit of careful coaching from the driver to keep up the work! On the right is Lies, who is more experienced and who dragged Nel with her at times — which annoyed her a bit. “Lies” and “Nel” are quite old-fashioned Dutch women’s names, I like that.
Klik and her mother toasting with almost-empty liquor glasses
Apparently the stable has a side-business making some kind of flavoured rum, and of course they gave people a taste and made sure to tell them where they could get it…
Us in front of a "I (heart) Texel" sign
Apart from all of the troubles, it was once again a good vacation. We’ve already made the reservations for next year.

On the Friday we would leave, the second ship wasn’t running either, so we left at the moment the camping gates opened — very early, but we didn’t want to take any chances. We got on the boat right away, so that went well. This also meant we were home a lot earlier than we would usually be, but that was not a problem at all: we could get our kitties from their ‘hotel’ one day earlier!

There is a ‘creative entrepreneur hub’ in the city, not far from where we live. It’s located in one of the old industrial buildings, which are all being repurposed, so the workshops tend to move around a bit. Big machinery gets shared, which makes it possible for smaller workshops to take on bigger projects they would otherwise could not.
Some of these workshops presented themselves on a “Maker’s Market” some time ago, and one of those was Suzan Doornbos, who makes objects from turned wood. This was something we had been curious about (there’s a shop in Arnhem that has all kinds of woodworking stuff, and we had been peeking through their windows at several occasions) and when I saw that she offered workshops, I took one of her cards to check it out.
So yesterday we went to her workshop to learn the basics of turning wood. There were three ‘students’: me, klik, and someone who had been making furniture for some time and who wanted to expand her repertoire.
(Also, I like the Dutch word ‘draaibank’ much better than the English ‘lathe’. ‘Draaibank’ literally means ‘turning bench’, which is so much more descriptive.)

A rectangular block of wood affixed in a lathe
We started off with a rectangular block of wood. Determine the center and then clamp it into the lathe.

Overview of the rectangular block of wood clamped in the lathe
An overview of the ‘turning station’ I used. When rotating the block by hand, in order to see that it would not bump into the ‘tool shelf’, I noticed that the rotation speed (the four-number display on the left) was measured independently from the motor input — it counted the rotations I did by hand. That makes a lot of sense, as you don’t have to calibrate motor input so carefully.

Me with a clear plastic face guard
Safety first! I look so fashionable in this…

The rectangular block rounded off with a coarse chisel in the foreground
Using a very coarse chisel, we chipped off the square edges to make the block round. Hard work, but once you got the feeling it wasn’t so bad.

The rounded block in the lathe, still a bit uneven
Still a bit uneven, but we’d use a much smaller chisel with much finer control to fix that. And really, you only can get fine details in once the block is rounded. The trick is to let the chisel glide across the wood, and you can’t do that if it’s not rounded off!

Me working at the lathe
Action shot.

A much smller chisel held in front of the much smoother block. One little spot on the left is still flat
With a much finer chisel, we made the block much smoother and more even. I had one little spot that still was straight. That was pointed out repeatedly, but I thought it would be cool to have one spot that reminded you that it all started out as a rectangular block of wood. (Spoiler: when finishing up the piece, I had to turn quite a bit of wood from that spot and I think it’s now completely gone. Too bad!)

A deep cut into the block
Then we learned how to make a deep cut. Not too deep, of course, otherwise you’d have two pieces instead of one… We used pencil lines as guides.

Two deep cuts in the block
And another cut made! The cuts can’t be straight down, because then the chisel gets too much friction from the sides of the ‘groove’ it is cutting, so you have to make smaller cuts next to it to give it room to go deeper.

The left-hand side of the space between the cuts has been rounded, but it's sorta straight
Then we learned how to ’round off’ one side. The movement is kinda tricky, so this first side is kinda straight. And once the wood has come off, you can’t add it back!

The right side of the space between the cuts is now rounded too. It is much rounder than the left side
The other side went much better! And it was not just me, everyone’s second side was better. Still, amazing how fast you can learn something like this. The cuts to the left and right are still rough, but of course I’d finish that up later with a much smaller chisel.

Action shot of me finishing up the rounding
Working very concentrated on getting the round shape right…

A 'hollow' in the block
Then we learned how to make a ‘hollow’. This was much harder, and my chisel ran away a few times. That left deep grooves on other parts of the block, so I had to carefully turn those away again, to make it smooth again. You can see that the cut below the round part has been smoothed out too.

The block with hollow to the left and rounding to the right. It is still rough around the edges
All the heavy lifting has now been done. The piece is still a bit rough around the edges, so I took a very fine chisel to finish it up.

Finished piece
The end result: this is as good as I was going to get it. Next was the sanding, with grit 180, 240 and 320 respectively. After the sanding it was really nice and smooth!

Two turned candlesticks, still a bit wobbly. A metal bit for holding a candle is placed on the left one
This is how our work came out of the lathe. Because there is always a bit of wood where the center-points go in, the ends are never smooth — so these candle holders are still wobbly! That would be fixed with a drill though. And there would also be a metal bit inserted at the top to hold the candle, so that the wood would not burn if the candle burned down too low! My work is on the left: I decided I wanted the round part on top. Klik’s work is on the right, and she wanted the hollow part on top.

Three wooden candle holders
This is the finished work of all the workshop participants. Mine on the left, Klik’s in the middle. The other participant had shaved her piece too far down to have the metal candle holder drilled all the way into the piece, as it was wider than the narrow part on top of her rounded part, so the metal bit sticks out.

It was a lot of fun, and I am amazed at how quickly you can learn the basics! Suzan also offers a second workshop to learn how to turn a wooden box, and that might be something for the future…


Today, we took our (semi-)annual outing to Keramisto, an international pottery and ceramics market. It’s a really fun mix of styles: some potters are really semi-mass producing mugs and plates, some make purely decorative objects, there were some making hyperrealistic animal figures this year, and everything in between. It is also one of the few markets where you’re actively encouraged to touch the wares.
The weather was mostly fine, we did get a bit of rain, but it wasn’t too bad. And luckily everything on sales could get wet without any ill effect too.

But with the occasional rain, the self-absorbed baby-boomers that are always out in force whenever something ‘arty’ happens, all walked around with big umbrellas without a care for what was happening around them. We regularly found ourselves crowded out of market stalls by people with umbrellas — they even kept them open even though all the stalls were covered… I did not very much enjoy that aspect.

Of course, there were many beautiful things on display, and many things I didn’t really care for. There was nothing that really jumped out at me. There were several nice things, but nothing that I couldn’t live without. In the end, we bought a single mug with green crystal glazing, which we both like. We have a pair of saucers with such glazing, in blue.

Let’s hope for better weather next year!

RPG-a-Day #31

31 – When did you first take part in #RPGaDAY?
It’s a good thing that I have this blog to refer back to — turns out my first participation was in 2016!

…and that’s it for this year. Thank you if you followed along, and apologies for the spam if you didn’t!