<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
 <title>xmdr</title>
 <description>_Het_ blog (web log) van xmdr</description>
 <link>https://xmdr.nl/blog</link>
 <copyright>xmdr assumeert het kopiëerrecht op alles wat je aanraakt. Door dit blog of bericht te lezen ga je akkoord met deze overeenkomst.</copyright>
 <lastBuildDate>Wed, 19 Aug 2026 02:55:09 UTC</lastBuildDate>
 <pubDate>Wed, 19 Aug 2026 02:55:09 UTC</pubDate>
 <ttl>1800</ttl><item>
				<title>Als computers fietsen zijn, dan is AI een auto met Google Maps</title>
				<pubDate>Tue, 18 Aug 2026 00:00:00 UTC</pubDate>
				<description><![CDATA[<h1>Als computers fietsen zijn, dan is AI een auto met Google Maps</h1><blockquote> <p>“Computers are like a bicycle for the mind.”</p> <cite>Steve Jobs</cite> </blockquote>
<h2>Transport over het kennislandschap</h2>
<p>Tijdens een autorit ga je over een snelweg, zie je weinig van de omgeving, en leer je de route niet uit je hoofd omdat de navigatie is uitbesteed aan Google Maps, die tevens al je data doorsluist. Als je fietst daarentegen, dan hoor, ruik, en als je niet goed kunt fietsen voel je de omgeving ook. Je zit er midden in, en zal er veel meer van onthouden. En als je wandelt? Dan duurt het nog langer, maar dat betekent ook meer tijd om de omgeving en de route tot je te nemen. Wie weet loop je iets of iemand tegen het lijf of tref je toevallig een toevalstreffer.</p>
<p>Een nieuwsgierig en oplettend persoon komt interessante en/of handige paadjes tegen die concepten verbinden, op de voorwaarde dat er tijd en ruimte is om rond te kijken en te lopen. Als erop wordt gestuurd -- ofwel direct, dan wel via implicatie van competitie -- dat iedereen tegenwoordig maar met de auto moet, omdat het zoveel sneller/makkelijker/goedkoper/magischer/eiwitrijker is, raak je dat kwijt.</p>
<p><em>Haastige spoed is zelden goed</em></p>
<h2>Slechte modellen die in de weg zitten</h2>
<p>Bijvoorbeeld de AI overview van Google. Of Apple's samenvattingen van notificaties. Dit zijn gewoon domme, slechte modellen die in bovenstaande analoog van een brug af rijden. Ze zijn kut en niemand zit er op te wachten. De rest van het artikel gaat over frontier modellen.</p>
<figure>
  <img src="/src/media/aislop/one_reddit_user_says.webp" alt="ai meme">
  <figcaption>You're absolutely right</figcaption>
</figure>
<h2>Uitbesteden van nadenken</h2>
<p>Hoe meer je het nadenken uitbesteedt, hoe minder verbindingen er bijkomen in je hersens. Het is bekend dat kennis beter blijft plakken als je iets met de hand schrijft, in plaats van het typt. Maar wat als je het niet eens meer typt? Het uiterste hiervan is een grote berg AI-slop waarvan je geen idee hebt hoe het in elkaar steekt, en dus of het überhaupt wel goed in elkaar steekt.</p>
<p>Uitbesteden kon al voor de komst van AI: apps als PhotoMath waarmee je een foto van je wiskundehuiswerk kan maken en de computer doet de rest. En als je een hele periode Wolfram Alpha gebruikt, dan kom je er op de toets zonder rekenmachine achter dat je geen reet ervan hebt onthouden. Tutorials en StackOverflow posts die makkelijk te kopiëren en plakken zijn. Templates die je in kan vullen. Een Wikipedia artikel dat met een beetje geluk het specifieke detail heeft waar je naar op zoek bent (de rest lees je niet eens). Alles tot en met bedrijven die hele opdrachten uitbesteden aan de laagste bieders ergens op een ander continent.</p>
<p>Vaak als je zelf iets maakt of schrijft, dan ben je niet alleen bezig met het produceren van iets. Je maakt je eigen gedachtes ook helder voor jezelf. Denken door te schrijven. Als je dit laat doen door een knip-en-plak tutorial of een AI, krijg je het ook niet helder. Bijna elk idee zit vol met gaten, maar als je er niet zelf mee bezig gaat, ontdek je die gaten later of zelfs niet.</p>
<h2>Verdiepen en verbreden</h2>
<p>Als je loopt of fietst kom je ongewenste (of in ieder geval niet bewust gewenste), ontoepasbaar lijkende informatie tegen. Zo'n meander in het landschap van kennis zet je stiekem een beetje aan het denken; nu stel je een heel gerichte vraag aan AI, die een mooi recht paadje voor je baant. Op dat paadje mis je een hele hoop meanders. Ook ga je veel sneller en dieper het donkere oerwoud in, zonder dat je goed gegrond bent in de omliggende materie: een kapmes is niet bij het paadje inbegrepen, die moet je zelf verkrijgen, met behulp van discipline om je eerst te verbreden in plaats van te verdiepen. Zonder die verbreding heb je namelijk ook geen idee of het paadje wel mooi loopt, alleen dat het er aannemelijk uitziet. Je ontkomt er eigenlijk niet aan dat je het gebied gewoon moet kennen.</p>
<figure class="chart">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1100 380" style="width:100%;height:auto;display:block;">
<defs>
  <marker id="walk-arrow-dfs" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto-start-reverse">
    <path d="M0,0 L9,4.5 L0,9 z" class="walk-arrowhead"/>
  </marker>
  <marker id="walk-arrow-bfs" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto-start-reverse">
    <path d="M0,0 L9,4.5 L0,9 z" class="walk-arrowhead"/>
  </marker>
  <marker id="tree-arrow" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto-start-reverse">
    <path d="M0,0 L8,4 L0,8 z" class="tree-arrowhead"/>
  </marker>
  <style>
    /* Uses the host page's own theme variables (.dark / .light on an
       ancestor element) - only works when this SVG is inline in the DOM,
       not when loaded as an image or a separate document. */
    text { font-family: inherit; }
    .title      { font-size: 24px; font-weight: 700; fill: var(--txt); }
    .node-label { font-size: 16px; font-weight: 600; fill: var(--txt); }
    .caption    { font-size: 16px; font-weight: 600; fill: var(--txt); opacity: 0.75; }
    .node  { fill: var(--bkgContainer, var(--bkg)); stroke: var(--txt); stroke-width: 2; }
    .edge  { stroke: var(--txt); stroke-width: 2; fill: none; marker-end: url(#tree-arrow); opacity: 0.8; }
    .tree-arrowhead { fill: var(--txt); opacity: 0.8; }
    .walk  { stroke: var(--acct); stroke-width: 2.5; fill: none; stroke-dasharray: 6 5; stroke-linecap: round; }
    .walk-arrowhead { fill: var(--acct); }
  </style>
</defs>

<text x="275" y="40" text-anchor="middle" class="title">Depth-First Search</text>
<text x="825" y="40" text-anchor="middle" class="title">Breadth-First Search</text>

<g>
<line x1="256.7" y1="110.5" x2="193.3" y2="164.5" class="edge"/>
<line x1="293.3" y1="110.5" x2="356.7" y2="164.5" class="edge"/>
<line x1="163.8" y1="201.2" x2="136.2" y2="253.8" class="edge"/>
<line x1="186.2" y1="201.2" x2="213.8" y2="253.8" class="edge"/>
<line x1="363.8" y1="201.2" x2="336.2" y2="253.8" class="edge"/>
<line x1="386.2" y1="201.2" x2="413.8" y2="253.8" class="edge"/>
<line x1="245.0" y1="106.0" x2="190.7" y2="152.2" class="walk" marker-end="url(#walk-arrow-dfs)"/>
<line x1="151.3" y1="201.4" x2="129.2" y2="243.3" class="walk" marker-end="url(#walk-arrow-dfs)"/>
<line x1="155.0" y1="286.0" x2="195.0" y2="286.0" class="walk" marker-end="url(#walk-arrow-dfs)"/>
<line x1="244.5" y1="249.7" x2="343.8" y2="186.8" class="walk" marker-end="url(#walk-arrow-dfs)"/>
<line x1="351.3" y1="201.4" x2="329.2" y2="243.3" class="walk" marker-end="url(#walk-arrow-dfs)"/>
<line x1="355.0" y1="286.0" x2="395.0" y2="286.0" class="walk" marker-end="url(#walk-arrow-dfs)"/>
<circle cx="275.0" cy="95.0" r="24" class="node"/>
<text x="275.0" y="101.0" text-anchor="middle" class="node-label">A</text>
<circle cx="175.0" cy="180.0" r="24" class="node"/>
<text x="175.0" y="186.0" text-anchor="middle" class="node-label">B</text>
<circle cx="375.0" cy="180.0" r="24" class="node"/>
<text x="375.0" y="186.0" text-anchor="middle" class="node-label">C</text>
<circle cx="125.0" cy="275.0" r="24" class="node"/>
<text x="125.0" y="281.0" text-anchor="middle" class="node-label">D</text>
<circle cx="225.0" cy="275.0" r="24" class="node"/>
<text x="225.0" y="281.0" text-anchor="middle" class="node-label">E</text>
<circle cx="325.0" cy="275.0" r="24" class="node"/>
<text x="325.0" y="281.0" text-anchor="middle" class="node-label">F</text>
<circle cx="425.0" cy="275.0" r="24" class="node"/>
<text x="425.0" y="281.0" text-anchor="middle" class="node-label">G</text>
</g>
<g>
<line x1="806.7" y1="110.5" x2="743.3" y2="164.5" class="edge"/>
<line x1="843.3" y1="110.5" x2="906.7" y2="164.5" class="edge"/>
<line x1="713.8" y1="201.2" x2="686.2" y2="253.8" class="edge"/>
<line x1="736.2" y1="201.2" x2="763.8" y2="253.8" class="edge"/>
<line x1="913.8" y1="201.2" x2="886.2" y2="253.8" class="edge"/>
<line x1="936.2" y1="201.2" x2="963.8" y2="253.8" class="edge"/>
<line x1="795.0" y1="106.0" x2="740.7" y2="152.2" class="walk" marker-end="url(#walk-arrow-bfs)"/>
<line x1="755.0" y1="169.0" x2="895.0" y2="169.0" class="walk" marker-end="url(#walk-arrow-bfs)"/>
<line x1="900.9" y1="200.9" x2="707.0" y2="274.6" class="walk" marker-end="url(#walk-arrow-bfs)"/>
<line x1="705.0" y1="286.0" x2="745.0" y2="286.0" class="walk" marker-end="url(#walk-arrow-bfs)"/>
<line x1="805.0" y1="286.0" x2="845.0" y2="286.0" class="walk" marker-end="url(#walk-arrow-bfs)"/>
<line x1="905.0" y1="286.0" x2="945.0" y2="286.0" class="walk" marker-end="url(#walk-arrow-bfs)"/>
<circle cx="825.0" cy="95.0" r="24" class="node"/>
<text x="825.0" y="101.0" text-anchor="middle" class="node-label">A</text>
<circle cx="725.0" cy="180.0" r="24" class="node"/>
<text x="725.0" y="186.0" text-anchor="middle" class="node-label">B</text>
<circle cx="925.0" cy="180.0" r="24" class="node"/>
<text x="925.0" y="186.0" text-anchor="middle" class="node-label">C</text>
<circle cx="675.0" cy="275.0" r="24" class="node"/>
<text x="675.0" y="281.0" text-anchor="middle" class="node-label">D</text>
<circle cx="775.0" cy="275.0" r="24" class="node"/>
<text x="775.0" y="281.0" text-anchor="middle" class="node-label">E</text>
<circle cx="875.0" cy="275.0" r="24" class="node"/>
<text x="875.0" y="281.0" text-anchor="middle" class="node-label">F</text>
<circle cx="975.0" cy="275.0" r="24" class="node"/>
<text x="975.0" y="281.0" text-anchor="middle" class="node-label">G</text>
</g>

<text x="275" y="345" text-anchor="middle" class="caption">Volgorde: A &#8594; B &#8594; D &#8594; E &#8594; C &#8594; F &#8594; G</text>
<text x="825" y="345" text-anchor="middle" class="caption">Volgorde: A &#8594; B &#8594; C &#8594; D &#8594; E &#8594; F &#8594; G</text>
</svg>
<figcaption>DFS duikt eerst diep; BFS werkt laag voor laag.</figcaption>
</figure>
<p>Het doet me denken aan <em>depth first search</em> en <em>breadth first search</em>. Als kennis een hiërarchie is met vertakkingen van het basale naar het specifieke, hoe dieper hoe specifieker, dan is een AI-antwoord een pad dat diep de hiërarchie in duikt, maar totaal niet breed. Als je iets met de hand doet, boeken zoekt en openslaat, ben je in de breedte bezig, want een boek met kennis op een te diep niveau begrijp je niet, en bewaar je voor wanneer je het basale niveau begrijpt. AI doet dat niet, en geeft je het misleidende gevoel dat de basiskennis überhaupt niet nodig is. Terwijl je ook juist betere prompts kan maken en dus betere antwoorden kan krijgen als je de basiskennis wel hebt.</p>
<p>En als je nou AI gebruikt om eerst te verbreden? Joh, wie houden we gek. Morgen ben je het weer vergeten. Je moet het echt zelf verwerken, er zelf wat mee doen, anders krijgt het geen grip op de synapsen.</p>
<h2>(AI) slop</h2>
<p>De herkomst van een tekst, codebase, afbeelding, wat voor artefact dan ook, boeit me niet zo. Of het nou gemaakt is door een persoon of AI. Wat mij belangrijk is, is dat het waarheidsgetrouw, accuraat, en samenhangend is. Kwaliteit. Dat er aandacht en moeite in is gestopt. Helaas lijken veel mensen dit niet te delen met mij. Zij vinden het "goed genoeg". Deels hebben ze misschien geen oog voor kwaliteit, deels vinden ze het misschien niet belangrijk. We leven natuurlijk in een wereld waar we stomme dingen moeten doen terwijl we liever iets anders zouden doen.</p>
<p>Zo wordt alles steeds meer uitgehold. Zelfs de beroemde IKEA Kallax kast is tegenwoordig holler dan hij al was. Te veel mensen produceren slop, en te veel nemen genoegen met slop, AI of niet. Als het maar makkelijk is. Als het maar goedkoop is. Als het maar meer winst geeft. Wie weet wordt het AI-slop fenomeen zo erg, dat mensen massaal met hun neus in de zure vlaai worden gedrukt, en er een algehele opstand tegen slop ontstaat. En wie weet is de zon morgen van water.</p>
<p>In de jaren 1800 werd broodmeel aangelengd met allerlei rotzooi. Dat is ingeperkt niet omdat mensen ineens een gevoel van eer kregen, en van de zondes van hebzucht en luiheid verlost waren, maar omdat er keiharde regulatie kwam. Als we kwaliteit willen, dan moeten we het forceren. Want je kan ervan uitgaan dat mensen (en de natuur over het algemeen) <i>the path of least resistance</i> nemen.</p>

<h2>AI slop</h2>
<p>Mensen die een gedachte hebben, een prompt ter grootte van een tweet schrijven, en daarmee een artefact "one-shotten", daar heb ik dus een probleem mee. Want die mensen hebben niet gewandeld en ook niet gefietst. Ze zijn gewoon met plankgas de auto ingestapt, en in rap tempo nergens naartoe gereden. Dat is geen kwaliteit, dat is slop. Laat me dan liever je prompt zien.</p>
<p>Als je met je ogen knijpt, dan lijkt het een goed product. Een wijs artikel, een leuk plaatje, een handige infographic. Maar zodra je inzoomt op details valt het uit elkaar als nat WC-papier.</p>
<p>En ja, de oppervlakkige stylistische "keuzes" zoals em-streepjes en overmatig gebruik van stijlfiguren zijn irritant. De gehele stem waarin het is geschreven is irritant. Want iedereen gebruikt een kleine selectie uit een klein assortiment AI-modellen. Het is alsof ineens de helft van alles is geschreven door dezelfde auteur. Natuurlijk gaat dat vervelen, AI of niet.</p>
<p>Maar wat me vooral dwarszit zijn de oxymoronen, het onnodig voorzichtige (of juist onnodig zelfverzekerde) taalgebruik (zonder de uitzonderingen te noemen die zulk voorbehoud dan zouden valideren). Tegelijkertijd een nauw, specifiek paadje, maar ook vaag en oppervlakkig. Het is, in één woord, gewoon niet helder maar troebel. (Dat waren eigenlijk twee woorden, oeps, je hebt helemaal gelijk.)</p>
<h2>Hoe ik AI gebruik</h2>
<h3>Code schrijven</h3>
<p>Tegenwoordig gebruik ik AI om veel code te schrijven. Dingen die eerst een middag of een dag zouden duren, gaan nu snel. Ik kan specifiek sturen (wat ik vaak moet doen, met een enkele prompt kom ik er nooit), want ik weet al wat er mis kan gaan, of wat juist goed zou werken. Zelfs dan is de code soms erg slecht. Daarnaast moet ik de code lezen en begrijpen. Als ik dat niet doe, begin ik steeds meer achter te lopen, en op den duur kan ik niet meer effectief sturen omdat ik gewoon mentaal niet gegrond ben in de code.</p>
<p>Hiervoor gebruik ik Claude. Ik verander niet te veel aan het basisprompt, maar ik heb wel skills die bepaalde patronen vastleggen. Bijvoorbeeld dat ik met Claude git patches over en weer stuur, in plaats van bestanden. Ik zorg dat projecten een duidelijke README.md hebben met belangrijke punten over bijvoorbeeld de architectuur en bepaalde patronen of uitzonderingen. Dit maakt het makkelijk om diffs te bekijken, specifieke dingen ongedaan te maken, en het AI-gesprek branchen gaat hand in hand met een nieuwe git branch. Aan het eind van een chat kan ik vragen waar de AI moeite mee had, dan kan ik daarop de README aanpassen.</p>
<p>Claude Code gebruik ik niet; ik gebruik alleen de chatversie. Ik heb geen zin om de omgeving te sandboxen, en vertrouw het anders niet. En ik ben bang dat toegeven aan het gemak ten koste zal gaan van de discipline om me te verbreden en gegrond te houden.</p>
<p>Quality of life dingetjes, die eerder geen prioriteit hadden, kan ik nu snel met AI ontwikkelen. Dit is eigenlijk het tegenovergestelde van slop: ik denk na over wat ik maak, en steek extra tijd en moeite in het afwerken, omdat AI een hoop tedium wegneemt wat daar eerder bij kwam kijken. Bijvoorbeeld het diagram van DFS/BFS, met een paar prompts en wat handwerk een nette illustratie die dit artikel anders niet had gehad.</p>
<h3>Onderzoeken</h3>
<p>In het apocalyptische landschap van internetzoekresultaten kan AI wat verlichting brengen. Met behulp van tool calling kan een AI ongehallucineerde, relevante, en recente informatie verkrijgen, mits die informatie zelf geen AI-hallucinatie is, of anderzijds (SEO-) spam. Het samenvatten van de informatie gaat minder goed. Ik merk dat, wanneer ik doorvraag, ik vaak een antwoord krijg dat begint met iets van "je hebt gelijk, dat had ik mis, dat heb ik te vlug gezegd, daar heb ik niet aan gedacht, dat heb ik over het hoofd gezien". Een frustrerende ervaring, maar ik zie het als de ene frustratie voor een andere ruilen. Het loont om de opgehaalde bronnen gewoon zelf door te nemen.</p>
<p>Het feit is gewoon dat een hedendaags frontier AI-model op een werkelijk gigantische dataset aan informatie is getraind*. En je weet niet wat je niet weet. Dus als ik een vaag en slecht idee heb, dan kan de AI het alsnog in een aannemelijke context plaatsen, en mij toegang verlenen tot mij-onbekende onderwerpen of vakjargon. Het is dus nuttig voor momenten waarop ik niet eens weet waar ik moet beginnen. Want zelfs als je graag meandert, kom je nooit alles vanzelf tegen.</p>
<p>De keerzijde is dat ik minder snel geneigd ben om dingen te vragen of overleggen met andere mensen. Ik vermoed dat ik niet te enige ben. Het is zó verleidelijk om naar een AI te gaan, die er 24/7 is, direct reageert, zonder iets van je te vinden. Ik probeer soms bewust dingen te vragen aan mensen, juist voor de verbinding en <em>serendipity</em> die een AI niet kan bieden, maar het kost wel meer moeite.</p>
<p>* De ethiek rondom de manier waarop deze datasets vergaard worden is over het algemeen ook belabberd.</p>]]></description>
				<category domain="https://xmdr.nl/essays">essays</category>
				<link>https://xmdr.nl/read/ai-slop</link>
				<guid isPermaLink="true">https://xmdr.nl/read/ai-slop</guid>
			</item><item>
				<title>Semafoor</title>
				<pubDate>Tue, 06 Aug 2024 00:00:00 UTC</pubDate>
				<description><![CDATA[<h1>Semafoor</h1><p>Je staat voor het imposante gebouw. Je kijkt omhoog, naar de top. Leuk om van te bungeejumpen zonder touw misschien. Weer omlaag. <i>Zucht.</i> Naar binnen dan maar. In de hoop dat je je hoofd in het hier en nu kan krijgen, kijken je ogen wat rond, naar willekeurige vormen en voorwerpen. Je voeten doen zoekend mee, alsof je een verdwaalde pelgrim in een kathedraal bent die een onzichtbaar labyrint volgt, een mozaïek met meer kronkels dan tegels. Mensen trekken hun wenkbrauw op, en voelen zich op hun hoede. <i>Wie is dit? Wat komt hij hier doen? Hij wijkt af van de norm, dus op welke manieren wijkt hij nog meer af? Ben ik in gevaar? Gaat hij iets raars zeggen of doen? Een ongemakkelijk en vervelend gevoel omarmd mij, hoe kom hier toch in godsnaam zo snel mogelijk van af!?</i> Ze willen je niet helpen, integendeel, ze willen zo snel mogelijk ontsnappen, als ze überhaupt al de klauwen van een interactie niet konden ontkomen. Je voelt het aan, al je ledematen zitten in de weg, en je voelt je bezwaard om te bestaan. Je longen zijn in paniek en je hart ontploft. Als een microfoon die voor de speaker wordt gehouden versterkt de gemeenschappelijke misère zich; als een stinkende drol in een te druk zwembad kabbel je dwars door het sociale vaarwater heen. Hoe lang nog voordat iemand de badmeester roept??</p>

<p>Je kijkt wat rond over de parkeerplaats. Als het paard van Sinterklaas springt je blik over de daken van de geparkeerde bolides, op zoek naar jouw autootje. Wie weet heeft hij wel pootjes gekregen! Ah, daar! Gelukkig, hij staat er nog (op wielen). Hoofdingang! Nou, dit is de plek; hier moet je zijn. Naar binnen dan maar. Spannend! Je kijkt wat rond naar de architectuur, maar, op zoek naar gezichten, balies, liften, trappen, en genummerde deuren, wijkt je lijn van zicht niet te ver af naar boven of beneden. Een vriendelijke mevrouw staat ineens met een glimlach voor je, en met een mengsel van enthousiasme en opluchting voel je aan dat je in goede handen bent.</p>

<p>Laconiek loop je de tent binnen, naar je doel toe. In je pas aarzel je niet. Je benen, niet je ogen, zijn aan het wandelen. Niemand kijkt een tweede keer naar je om, en niemand vraagt je vriendelijk waar je moet zijn. Als een tandwiel in een gesmeerd mechaniek baan je je een weg door de mensen. Je loopt een deur door waar "Alleen personeel" op staat. Er zijn wat mensen, je geeft een knik en een groet, en loopt zonder meer door. Niemand zegt er wat van, ze zijn alweer terug bij hun gesprek over wiens vakantie het verste weg was.</p>]]></description>
				<category domain="https://xmdr.nl/verhalen">verhalen</category>
				<link>https://xmdr.nl/read/semafoor</link>
				<guid isPermaLink="true">https://xmdr.nl/read/semafoor</guid>
			</item><item>
				<title>Waarom ik (niet) post</title>
				<pubDate>Tue, 23 Jul 2024 00:00:00 UTC</pubDate>
				<description><![CDATA[<h1>Waarom ik (niet) post</h1><p>En weer een hiaat van maanden sinds mijn laatste (non-shit)post. Maar waarom? Of eigenlijk, waarom niet? Als ik wèl post, waarom dan ineens wel weer?</p>
<p>Ik schrijf om de volgende redenen:</p>
<ul>
<li>als geheugensteuntje voor de volgende keer dat ik iets soortgelijks moet doen of bedenken</li>
<li>als therapie, om irritaties van me af te schrijven </li>
<li>om beter over dingen na te denken en ideeën uit te werken</li>
<li>ik lees mezelf graag praten</li>
</ul>
<p>Publiceer om:</p>
<ul>
<li>mezelf te promoten, staat goed op m&#39;n cv enz enz</li>
<li>anderen met soortgelijke problemen of ideeën te helpen</li>
<li>discussies met lezende vrienden en familie uit te lokken</li>
<li>mailtjes van wildvreemden te krijgen dat Mark Rutte inderdaad een klootzak is</li>
</ul>
<p>Toevallig had ik het laatst met mijn vader over stress, en de invloed van dingen waar je maar niet aan toe lijkt te komen, die je jezelf volledig vrijwillig hebt opgelegd zonder schijnbare reden. Bijvoorbeeld het schrijven van een blogpost over iets wat je hebt gedaan of bedacht.</p>
<p>Algemeen gezien houd ik mijn shit bij met een issue board: ik bedenk wat ik wil doen met mijn leven en schrijf de benodigde taken uit, en die leiden dan een leven in de vorm van een ticket, verhuizende van de &quot;todo&quot;-kolom naar &quot;researching&quot; naar &quot;doing&quot; en dan uiteindelijk over de Jordaan naar &quot;done&quot; danwel &quot;don&#39;t&quot;. </p>
<p>En ja, ook ideeën voor blogposts ondergaan deze lijdensweg. Maar helaas komen ze niet vanzelf uit &quot;todo&quot;. Er is natuurlijk een reden dat ik sommige posts al meer dan een jaar uitstel: ik voel er niet echt passie voor, het is puur dat ik het mezelf heb opgelegd, want het zou zo leuk staan op mijn blog. Nou, dan documenteer ik ze hier maar kort en daarmee schrijf ik ze (van me) af.</p>
<h2 id="raytracing-op-de-rekenmachine">Raytracing op de rekenmachine</h2>
<p><img class="right" src="/src/media/waarom_ik_niet_post/reflectie.png" alt="3 balletjes met reflecties maar zonder shading" title="3 balletjes met reflecties maar zonder shading"></p>
<p>Ik heb 3 jaar geleden <a href="https://gitlab.com/xmdr/illumina">een raytracer</a> geschreven, en ook zo&#39;n 3 jaar geleden een port gemaakt voor mijn TI-84 Plus CE-T. Heb het niet eens afgekregen want alleen al het renderen van de raycasting zelf (hit/no hit) duurt een fucking uur op de 320×240 ingebouwde LCD, gewoon niet boeiend. Misschien een half gebakken discussie over fixed point getallen i.p.v. ints en floats (alhoewel het stiekem gewoon ints zijn, zie het als rekenen met &quot;millimeters&quot; ipv &quot;meters&quot; als het SI stelsel gebaseerd was op machten van 2 en niet 10). <p>
<p><img class="right" src="/src/media/waarom_ik_niet_post/glitchy.png" alt="glitchy balletje" title="glitchy balletje"></p>
<p>Wow deze render van een bal laat een patroon van floating point inaccuracies zien ofzo omdat ik hier de epsilon was vergeten in mijn floating point comparisons voordat ik overstapte naar fixed point omdat deze rekenmachine van €100+ uit 2013 een 8 bit chip van de jaren 70 gebruikt die helemaal geen FPU heeft waardoor alle FLOPs in software geëmuleerd moeten worden wat FUCKING TRAAG IS.</p>
<h2 id="routerfirmware-flashen">Routerfirmware flashen</h2>
<p>Voor mijn moeder heb ik haar Ziggo wifi repeater ding (een TP-Link Archer C7 maar dan met Ziggo branding) geflasht zodat alle features van de router weer beschikbaar waren, in plaatst van een softwarematige beperking op alles behalve wifi repeating. Dit was een hele opgave en op zich een leuke uitdaging, maar uiteindelijk kwam het er neer op &quot;ik had al Linux geïnstalleerd, weet een terminal te gebruiken, kan een <a href="https://gathering.tweakers.net/forum/list_messages/1674027/0">relevant Tweakers thread</a> vinden (vereist niet alleen serieuze skills maar ook luck), kan desbetreffende thread lezen en volgen, kan een obscuur protocol genaamd <a href="https://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocol">TFTP</a> gebruiken met commandline tools ervoor&quot;.</p>
<p>Het had gewoon niet echt de potentie om een waardevolle write-up te zijn dus, want dit probleem ga ik niet opnieuw krijgen (en anders heb ik het nu alsnog stiekem voor mezelf vastgelegd), en mijn post zou andere mensen niet beter helpen dan het Tweakers thread. En ik heb voor de grap zelfpromotie wel bovenaan gezet, maar eigenlijk is dat de laatste reden waarom ik iets zou posten. Laat je niet foppen door de stem waarmee ik schrijf - ik heb helemaal geen behoefte om mijn ego te voeden en de wereld te laten zien hoeveel slimmer ik wel niet ben dan de rest, alleen maar omdat ik als kind niet met vrienden maar met een computer speelde waardoor ik wel weet hoe ik Arch Linux moet installeren maar niet weet hoe gezond sociaal contact verloopt.</p>
<h2 id="braille-en-anonium">Braille en Anonium</h2>
<p>Ik had een keer het idee om een imageboard/forum a la 4chan te maken, maar dan federated en bedoeld voor intelligente en inhoudelijke discussies door middel van een <a href="https://github.com/ballerburg9005/IQcaptcha">automatisch gegenereerde mini IQ test als captcha</a> (lol! Haha mensenproblemen oplossen met tech die is zeker van gisteren!&quot;&gt;&lt;/a&gt;.&quot;)}&quot;DROP TABLE users;--&quot;,:1;uitroepteken).</p>
<p>Uiteindelijk enkele posts mogen hosten op die site maar het liep geen vaart, en ik kwam er al heel snel achter wat een &quot;4chan achtig imageboard&quot; precies inhoudt qua publiek dat je ermee trekt. Een hoog IQ zegt dus niks over de volwassenheid of beleefdheid van een persoon, zeker niet als je die hebt vastgesteld met een enkele <em>progressive matrix test</em>. Dus stekker eruit en snok. Maar nu komt het!</p>
<p>Posters waren anoniem, maar wel uniek gekenmerkt met een computer gegenereerd pseudoniem, was het idee. Hoe geef je dat weer? Bitcoin heeft <a href="https://github.com/bitcoin/bips/blob/master/bip-0039">een woordenlijst + algoritme</a> om de binaire seeds van wallets te vertalen naar een reeks wartaal, wat beter te lezen en onthouden is voor mensen (die kunnen lezen). Maar <em>ik</em> had het bril-jànte idee om de bits grafisch te vertonen. En wat lijkt daarop? Braille! Eén bolletje of géén bolletje, 1 of 0. Braille heeft in Unicode 2 soorten tekens: matrixen van 2×3 stipjes per teken en matrixen van 2×4 stipjes per teken. Ik ging voor de 2×4, want 128 bits <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">(een GUID)</a> = 2×4×16 braillebolletjes.</p>
<p>Helaas kon ik geen font vinden die zowel braille als mijn esthetische visie ondersteunde. Dus ik maakte mijn eigen vector font (svg font). Dat was veel werk dus ik schreef een script. Die dealde er ook mee dat de <a href="https://en.wikipedia.org/wiki/Braille_Patterns#Identifying,_naming_and_ordering">officiële volgorde van de Braillebolletjes</a> wat apart is vanwege historische redenen.</p>
<p><strong>Intussen is in elke moderne browser support voor SVG fontfaces geschrapt.</strong> En achteraf had ik net zo makkelijk (makkelijker) gewoon direct SVG kunnen genereren in de HTML want uiteindelijk was er eigenlijk geen enkele overeenkomst met braille behalve dat er sprake was van een matrix van stippeltjes. Niet alsof een blinde een braille-afdruk gaat maken van de pagina en dan zegt &quot;oh ja, dit is weer typisch een argument van WV#%
™£ ˚¯$£™¸ ̣˘$V T?JKL÷Ä P*&quot;.</p>
<p>Het meest poignante onderdeel was de PHP UTF-8 encoder en decoder die ik ervoor had gemaakt, en überhaupt het feit dat een taal als PHP over bitwise operators beschikt. Alsnog lekker geprutst!</p>
<pre><code class="lang-php"><span class="php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">utf8</span><span class="hljs-params">($num)</span></span>{
    <span class="hljs-keyword">if</span>($num&lt;=<span class="hljs-number">0x7F</span>)       <span class="hljs-keyword">return</span> chr($num);
    <span class="hljs-keyword">if</span>($num&lt;=<span class="hljs-number">0x7FF</span>)      <span class="hljs-keyword">return</span> chr(($num&gt;&gt;<span class="hljs-number">6</span>)+<span class="hljs-number">192</span>).chr(($num&amp;<span class="hljs-number">63</span>)+<span class="hljs-number">128</span>);
    <span class="hljs-keyword">if</span>($num&lt;=<span class="hljs-number">0xFFFF</span>)     <span class="hljs-keyword">return</span> chr(($num&gt;&gt;<span class="hljs-number">12</span>)+<span class="hljs-number">224</span>).chr((($num&gt;&gt;<span class="hljs-number">6</span>)&amp;<span class="hljs-number">63</span>)+<span class="hljs-number">128</span>).chr(($num&amp;<span class="hljs-number">63</span>)+<span class="hljs-number">128</span>);
    <span class="hljs-keyword">if</span>($num&lt;=<span class="hljs-number">0x1FFFFF</span>)   <span class="hljs-keyword">return</span> chr(($num&gt;&gt;<span class="hljs-number">18</span>)+<span class="hljs-number">240</span>).chr((($num&gt;&gt;<span class="hljs-number">12</span>)&amp;<span class="hljs-number">63</span>)+<span class="hljs-number">128</span>).chr((($num&gt;&gt;<span class="hljs-number">6</span>)&amp;<span class="hljs-number">63</span>)+<span class="hljs-number">128</span>).chr(($num&amp;<span class="hljs-number">63</span>)+<span class="hljs-number">128</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-string">''</span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GUID</span> </span>{
    <span class="hljs-keyword">public</span> $bytes;

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span><span class="hljs-params">($bytes = false)</span></span>{
        <span class="hljs-keyword">if</span> ($bytes === <span class="hljs-keyword">false</span>){
            <span class="hljs-keyword">$this</span>-&gt;bytes = random_bytes(<span class="hljs-number">16</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">$this</span>-&gt;bytes = $bytes; 
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toHex</span><span class="hljs-params">()</span></span>{
        <span class="hljs-keyword">return</span> bin2hex(<span class="hljs-keyword">$this</span>-&gt;bytes);
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toBraille</span><span class="hljs-params">()</span></span>{
        $braille = <span class="hljs-string">""</span>;
        <span class="hljs-keyword">foreach</span> (str_split(<span class="hljs-keyword">$this</span>-&gt;bytes) <span class="hljs-keyword">as</span> $byte) {
            $braille .= utf8(<span class="hljs-number">0x2800</span>+hexdec(bin2hex($byte)));
        }

        <span class="hljs-keyword">return</span> $braille;
    }
}</span>
</code></pre>
]]></description>
				<category domain="https://xmdr.nl/blog">blog</category>
				<link>https://xmdr.nl/read/waarom_ik_niet_post</link>
				<guid isPermaLink="true">https://xmdr.nl/read/waarom_ik_niet_post</guid>
			</item><item>
				<title>Paar tientjes</title>
				<pubDate>Sat, 22 Jun 2024 00:00:00 UTC</pubDate>
				<description><![CDATA[<h1>Paar tientjes</h1><p>Ach, voor die paar tientjes... Honderd euro is maar tien tientjes! En hoe veel is duizend? Tien tien tientjes! Dus wat maakt het dan nog uit? Spendeer uw tientjes dan toch even rijkelijk als zorgeloos!</p>]]></description>
				<category domain="https://xmdr.nl/blog">blog</category>
				<link>https://xmdr.nl/read/paar_tientjes</link>
				<guid isPermaLink="true">https://xmdr.nl/read/paar_tientjes</guid>
			</item><item>
				<title>Django migration migraine</title>
				<pubDate>Sat, 20 Apr 2024 00:00:00 UTC</pubDate>
				<description><![CDATA[<h1>Django migration migraine</h1><p>Het was een tijd en een plaats. Ik - oke, ik stop met dit flauwe gedoe. Het was ochtend en ik zat achter mijn bureau. Ik was bezig met een kleine refactor van wat code. Dacht ik. </p>
<p>Voor een nieuwe module waar ik mee bezig was, had ik een aantal zogeheten Models gemaakt. Dit is doorgaans Object Oriented jargon voor &quot;database tabel&quot;.</p>
<p>Normaal hebben database tabellen een identificatie column, de <em>primary key</em>. Vaak een getal. &quot;Dit is rij nr. 593 in de tabel&quot;. Maar mijn model moest over op willekeurige UUIDs, want de rest van de models in de code waren ook zo, en allerlei onderdelen berusten op die impliciete(!) standaard. Een UUID is ook een getal, maar dan van 32 hexadecimale cijfers (want 128 bits). En niet oplopend zoals de typische <code>ID INT PRIMARY KEY</code> is.</p>
<p>Een simpele klus, want het hele idee van een Object Relational Mapper zoals Django is dat je je Modellen kan uitdrukken in de object oriented programmeertaal waar je in werkt, en dat Django onder de motorkap met de database stoeit om het gewoon te laten werken. Ik zou gewoon een regeltje code aan kunnen passen en dan zou het werken. Dus ik pas die model aan zodat het oude nummertje een andere naam had en niet meer de primary key was. Daarnaast had ik een nieuw UUID veld, primary key, toegevoegd.</p>
<p>Django had andere plannen.</p>
<p>Als je de models verandert, moet je <code>poetry run ./manage.py makemigrations</code> doen. Daarmee maakt Django ergens in het project een bestandje met stappen waarmee de database daadwerkelijk omgekat zal worden. Dan doe je <code>poetry run ./manage.py migrate</code>, zodat hij die bestandjes 1 voor 1 afgaat, waarop hij accuut zeikt dat hij niet 2 primary keys tegelijk kan hebben.</p>
<p>Wat doet Django nou, die domme malware (een worm, wan-ORM): Dat kut ding probeert eerst een nieuw primary key UUID veld te maken en <em>dan pas</em> het oude veld niet-primary te maken. Natuurlijk kun je niet 2 primary keys tegelijk hebben. Ik heb ook maar 1 BSN. Op dat moment wil ik er vanaf zijn en draai ik de 2 operaties om, en hij gaat verder.</p>
<p>Vervolgens zeikt hij over een <code>PROTECT</code>: er waren andere models gelinkt aan de veranderde model. De database snapt dan niet dat de primaire identificatie momentaan verdwijnt - dat brengt alle relaties in het geding. Maar waarom is dit mijn probleem? Waarom regelt Django dit niet gewoon??</p>
<p>Aangezien al die models toch nog geen instances hadden (in database parlance: alle tabellen zijn nog leeg), en er dus in feite nog geen relaties waren, flikkerde ik die ganse foreign key gewoon weg. Hop, geen <code>ON DELETE PROTECT</code> gezeik.</p>
<p>En daarna maakte ik een tweede migraine die dan de foreign key weer terug zet. Oh, en nu hij vraagt een default omdat hij denkt dat er misschien bestaande rijen kunnen zijn, waarvan de relatie dan natuurlijk onbekend is? Zucht! Nee Django, die bestaan niet, want al die models zijn spiksplinternieuw en nog leeg, maar dat kan ik je niet vertellen op een manier die je begrijpt! Dan maar <code>None</code> als default.</p>
<p>Dat accepteert hij, ook al is die foreign key column als &quot;not null&quot; geregistreerd(??). Bijzonder. En niet erg intuïtief. En niet erg logisch. En niet erg gebruiksvriendelijk. En niet erg goed doordacht. En niet echt geschikt voor professionele software.</p>
<p>In SQL was dit makkelijker geweest, en had ik het direct goed gedaan:</p>
<ol>
<li>In de andere tabellen, verwijder de foreign key relatie op <code>x</code> en hernoem de column naar <code>old_x_id</code>.</li>
<li>In tabel <code>x</code>, hernoem <code>id</code> naar <code>old_id</code> en verwijder primary</li>
<li>In tabel <code>x</code>, maak een UUID <code>id</code> en maak die primary</li>
<li>In de andere tabellen, maak de nieuwe foreign key <code>x_id</code>, door <code>tabel.old_x_id</code> te matchen aan <code>x.old_id</code> en dan <code>x.id</code> te selecten in <code>tabel.x_id</code>.</li>
</ol>
<p>Maar dat snapt Django niet. Dat weet Django niet. Ook al is het <em>the one job</em> die Django heeft.</p>
<p>Al met al heb ik toch te veel verwacht van Django de worm. Had ik kunnen zien aankomen: in Django kun je niet eens filters toepassen op &quot;calculated fields&quot;. (In database parlance, &quot;view&quot;, niet te verwarren met een &quot;view&quot; in het Model-View-Controller model (&quot;model&quot; hier niet te verwarren met Model in het ...))</p>
<p>Het wordt nog beter: ik dus na dit gedoe mijn migraine bestandje pushen naar mijn git branch; merge request maken om mijn branch naar main te mergen. Wat blijkt: iemand anders had al een &quot;migratie nr. 7&quot; gemaakt. Want ja, zo houdt Django dat bij! Dus nu krijg je tijdens een <code>poetry run ./manage.py migrate</code> gezeik over een <em>migration merge</em>. Bellissimo.</p>
<p>Ik zou graag willen zien van mijn collega&#39;s in het veld dat ze iets hogere standaarden krijgen voor de tools waar ze mee werken. En dat ze verder kijken dan hun OOP lang is. Als dat de standaard houding was geweest, had ik dit gezeik niet gehad. Was mijn energie en focus voor de dag niet opgeslokt door een onnodig zwart gat. Had ik gewoon de taak die ik eigenlijk erna had willen doen, kunnen doen.</p>

<p>&lt;/rant&gt;</p>
]]></description>
				<category domain="https://xmdr.nl/blog">blog</category>
				<link>https://xmdr.nl/read/django-migration-migraine</link>
				<guid isPermaLink="true">https://xmdr.nl/read/django-migration-migraine</guid>
			</item><item>
				<title>Nieuwe Malware: jupyter</title>
				<pubDate>Sun, 18 Feb 2024 00:00:00 UTC</pubDate>
				<description><![CDATA[<h1>Nieuwe Malware: jupyter</h1><p>Malware: malafide software.</p>
<br>
<p>Voor school moet ik per se jupyter notebook gebruiken. Eerste impressie.</p>
<p>Downloaden op manjaro is aids. Niet de schuld van jupyter. Ik moet <code>pip install jupyter</code> doen, maar pip klaagt dat ik al een package manager (pacman) heb en zegt dat ik <code>pacman -S python-jupyter</code> - ahem - <code>sudo pacman -S python-jupyter</code> moet doen. Nou, die package bestaat dus niet, dus dan toch maar <code>pip install jupyter --break-system-packages</code>.</p>
<p>Opstarten is interessant. Ik zoek <code>jupyter</code> in mijn startmenu. Er verschijnt een default applicatie icoontje. Klik - en er komt een terminal tevoorschijn. Dan volgt kort daarop een browserscherm met een soort file manager. Ook een popup of ik cookies of analytics of iets wil, geen idee, uit reflex klikte ik het weg voordat ik het kon lezen.</p>
<p>Ik had al een mapje, <code>/home/michael/uni/2a-scicomp</code>. Die kon jupyter niet vinden. Prima, dan maar die filemanager-achtige sidebar van jupyter gebruiken en handmatig navigeren...</p>
<p>Het bestand opent en het doet me denken aan Rdocs. Brrr. Ik klik dubbel op de blokjes gerenderde html en latex, en ze transformeren in een soort editable markdown. Ik edit het, maar geen idee hoe ik nu weer de latex krijg. Nogmaals dubbel klikken? Nee. Rechtermuis iets? Nope. Ik zie een &quot;herstart&quot; icoontje, dat maar doen. Hij klaagt iets over variabelen resetten. Geen flauw idee wat de implicaties zijn? Fuck it, we klikken oké. Maar nee hoor, geen latex. Zal wel.</p>
<p>Ik selecteer wat text. Rechtermuisknop: ik kan het niet kopiëren. Ik kan wel de "cell" kopiëren... Oke, dat dan maar? Ctrl+v ergens anders (gewoon in een DEGELIJKE editor) en dan krijg ik een heel andere snippet geplakt - iets van eerder op de dag. Dat werkt dus niet. Fijnnnn. Het domme is, de shortcut ctrl+C werkt dus wel normaal. Dus wat dat nou voor autistisch gedoe is met dat context menu, geen idee. Gelukkig heeft FireFox een oplossing voor irritante malware die je context menu kaapt, shift+rechterklik en bam, nu kan ik gewoon dingen kopiëren met de muis, zoals God het bedoeld heeft.</p>
<p>Kan ik dan ten minste dat terminal venster weg doen? Ctrl+D, ctrl+Z. Ah, die worden opgeslokt. Dus ik kan het process niet in de background verder laten gaan en dan disownen. Hmm, gewoon eens de terminal dicht klikken. Oh oeps, nu klaagt de webapp dat hij geen verbinding meer heeft met de server.</p>
<p>Dit wordt een lange, LANGE periode...</p>]]></description>
				<category domain="https://xmdr.nl/blog">blog</category>
				<link>https://xmdr.nl/read/nieuwe-malware-jupyter</link>
				<guid isPermaLink="true">https://xmdr.nl/read/nieuwe-malware-jupyter</guid>
			</item><item>
				<title>Waar ben ik nou weer aan begonnen</title>
				<pubDate>Sat, 09 Dec 2023 00:00:00 UTC</pubDate>
				<description><![CDATA[<h1>Waar ben ik nou weer aan begonnen</h1><img src="/src/media/piano/fabriek.png" alt="Illustratie van de Emerson pianofabriek">

<p>Een tijdje geleden heb ik voor mijn verjaardag een keyboard gekregen. Gewoon een simpel keyboard met 61 toetsen, hij heeft niet eens een midi uitgang. Maar het is leuk om weer muziek te spelen en hij bevalt me daarvoor prima. Het deed me denken aan mijn kindertijd: toen gingen we tijdens kerst naar mijn tante in Brabant, die op een oude boerderij woonde. Daar, diep weggestopt in het huis, was een koude en muffe biljartkamer, zonder ook maar één raam naar buiten. Hier werden de drukke kinderen naartoe gewezen, om zich te vermaken met de biljarttafel, hometrainer, dikke kist met speelgoed, en achterin een buffetpiano.</p>
<p>Door de jaren heen raakten sommige toetsen hun beleg kwijt, en andere toetsen kwamen vast te zitten. De toetsen die wel goed werkten, klonken niet volledig zuiver meer. Maar toch was het altijd hartstikke leuk om willekeurige combinaties in te drukken op dat ding! Inmiddels is dat huis verkocht en zal die arme piano wel ergens in een houtkachel beland zijn.</p>
<p>Je snapt waar dit naartoe gaat. En anders snap je het nu wel. En <em>anders</em> anders weet ik niets te zeggen over je situatie. Op een dag zat ik marktplaats af te struinen, gewoon nieuwschierig. Goh, zo veel buffetpianos. €300, €100, €50, gratis... Vraag me af waarom ze zo goedkoop zijn. En toen zag ik een bijzonder gave piano. Voor een bijzonder gave prijs. Op de foto zag hij er bijna uit als nieuw, al het beleg zat nog op de toetsen en de afwerking van het hout leek nog netjes.</p>
<p><img src="/src/media/piano/marktplaats.jpg" alt="Foto van Marktplaats"></p>

<p>Een antieke &quot;Emerson&quot;. Na een korte internet excursie vond ik op <a href='https://antiquepianoshop.com/online-museum/emerson/'>deze site</a> dat het een oud Amerikaans merk betreft, opgericht in 1849 en gestopt vanwege de tweede wereldoorlog. Op de site staan scans van meerdere catalogi (deze piano, een &quot;style 14&quot; is te vinden in die van 1889).</p>

<figure>
<img src="/src/media/piano/catalogus.png" alt="Foto van relevante cataloguspagina">
<figcaption>
<p>Style 14, Cabinet Grand Upright.</p>
<p>New scale, three strings or unisons, 7⅓ octaves, ivory keys, patent repeating action, new patent full iron plate, rolling fall, patent swing desk, engraved or bronze panels, engraving on front and ends, extra carved trusses and patent mouse-guard pedal feet.</p>
</figcaption>
</figure>

<figure>
<img src="/src/media/piano/restauratie.png" alt="Foto van gerestaureerde soortgelijke piano">
<figcaption>Een soortgelijke piano, gerestaureerd door Antique Piano Shop.</figcaption>
</figure>

<p>Snel maakte ik een afspraak, want ik zou wel niet de enige zijn die hem wilde hebben, al helemaal als hij gratis is...</p>
<p>Het was een wat koudere herfstdag, en ik reed op mijn trouwe brommer, gemaakt van echt Chinesium, naar het Groningse dorpje Huizen. Er werd door een vriendelijke vrouw opengedaan die mij naar de woonkamer begeleidde. Daar ontmoette ik de verkoper (weggever) John. Met hem liep ik weer de helft terug, naar een kamertje die mij qua mufheid aan de biljartkamer deed denken. Daar stond hij dan! De piano.</p>
<p>Het eerste wat mij opviel waren de krassen en beschadigingen op en aan het hout. Die waren op de foto toch minder duidelijk doorgekomen. Ook een aantal toetsen waren wat minder wit, maar nog wel intact! Toen ging ik maar eens kijken of hij nog geluid maakte. En ja! Elke toets deed het, alhoewel de een wat stroever dan de ander. En sommige toetsen kwamen niet meer omlaag. Maar de piano klonk prima. Er zat geen enkele toets bij die op zichzelf vals klonk, en de zuiverheid van akkoorden was ook niet te slecht. Zelfs de bassnaren klonken nog goed.</p>
<p>Ik deed de kap omhoog en keek bij de piano naar binnen. Het was in de piano erg stoffig, en het rook apart. Ik zag op het ijzeren frame een patentjaar, 1885-1886. Ik zag erop toe dat alle hamers en dempers nog bewogen, alhoewel sommige dus wat stroef. Enkele hamers bleven hangen in de aanslag. Ik bekeek het klankbord, en ik kon geen scheuren zien!</p>
<p>Ik wilde de achterkant even bekijken: een spinnenparadijs. Met enorm veel moeite kreeg ik samen met John de zware antieke piano een klein stukje van de muur af. Overal waren dunne grijswitte draadjes gespannen tussen de muur en de piano, die op mijn vest bleven plakken terwijl ik mijn best deed om zo veel mogelijk te zien in zo min mogelijk tijd.</p>
<p>Hierna vertelde hij mij doodleuk dat de piano al 40 jaar niet meer gestemd was. Het was van zijn broer geweest, die verhuisd was en geen ruimte meer had. Het was eigenlijk de bedoeling dat hij hem weer op zou halen, maar daar is het nooit van gekomen. Wat het verhaal van de piano daarvoor was, wist hij niet.</p>
<p>Al die tijd heeft de piano achter de vitrages gestaan, precies tussen 2 radiatoren in. Zo&#39;n beetje het ergste wat je kan doen! Gelukkig werd de ruimte nooit gebruikt en waren de radiators consistent uitgebleven. Vandaar dat hij nog zo goed klonk.</p>
<p>Dus. De piano is, gezien de leeftijd van 130+ jaar, in goede staat. Hij is gratis. Sommige toetsen lopen wat aan, maar het is allemaal gewoon hout en vilt; in principe goed zelf te repareren, had ik bedacht, met in mijn achterhoofd een aantal YouTube filmpjes van pianorestauraties. Ik vroeg hem wanneer de piano uiterlijk weg moest.</p>
<p>&quot;Dat moet wel lukken&quot;.</p>
]]></description>
				<category domain="https://xmdr.nl/blog">blog</category>
				<link>https://xmdr.nl/read/emerson-piano</link>
				<guid isPermaLink="true">https://xmdr.nl/read/emerson-piano</guid>
			</item><item>
				<title>Objectief Verkeerd Leven</title>
				<pubDate>Sat, 16 Sep 2023 00:00:00 UTC</pubDate>
				<description><![CDATA[<h1>Objectief Verkeerd Leven</h1><h2 id="wc-rol-verkeerd-om">WC-rol verkeerd om</h2>
<p>Als je een velletje wil vastpakken, waarom wil je dan je hand tegen de muur hebben? Waarom hang je de rol niet gewoon goed?</p>
<h2 id="alleen-droog-wc-papier">Alleen droog wc-papier</h2>
<p>En daarover: haal eens een smeuïge drol langs je gezicht. Smeer dit vervolgens uit met droge velletjes papier. Voel je je nu schoon?</p>
<h2 id="alles-met-de-afwasborstel">Alles met de afwasborstel</h2>
<p>Een afwasborstel is er alleen om de meest hardnekkige tjak van je shit af te schrobben. Wat zit je nou aan te klooien met die vork man? En zit er soms mineraalopbouw op dat glas ofzo? Een borstel maakt ook niet uniform schoon, want daar is het ook niet voor bedoeld, <em>het is bedoeld om shit los te krabben.</em> Tip: koop een spons. Shit, ze hebben tegenwoordig zelfs speciale afswassponsjes!</p>
<h2 id="kunststof-snijplanken">Kunststof snijplanken</h2>
<p>Zo te zien ben je hard bezig om zo veel mogelijk hormoonverstorende stoffen in je eten te krijgen; waarom doe je dat? Zelfde voor kunststof (kinder)bekers, bestek, kommetjes en borden, en zo voorts. Gebruik gewoon hout, rvs, keramiek, glas ofzo.</p>
<h2 id="waterfles-niet-schoonmaken-en-of-vervangen">Waterfles niet schoonmaken en/of vervangen</h2>
<p>bro...</p>
<h2 id="donkere-was-met-lichte-was-wassen">Donkere was met lichte was wassen</h2>
<p>Wow cool vaalgrijs shirt met pluisjesdesin!</p>
<h2 id="platgedrukte-tostis">Platgedrukte tostis</h2>
<p>Fuck you. Een compact brok brood is niet &quot;knapperig&quot;.</p>
<h2 id="oc-an-de-parfum">Océan de parfum</h2>
<p>Oh de toilet of oh de parfum kan lekker ruiken. Maar niet als je jezelf verdrinkt in die shit. Laat m&#39;n neus en longen met rust bitch.</p>
<h2 id="nieuwschierig-okselhaar">Nieuwschierig okselhaar</h2>
<p>Als het okselhaar uit je mauwen kruipt dan is het tijd om die shit te scheren want het staat crunchy as fuck. Waarom ziet het er ook altijd uit als een mishandelde struik en nooit eens à la Andrélon? Laat m&#39;n arme ogen met rust motherfucker.</p>
]]></description>
				<category domain="https://xmdr.nl/blog">blog</category>
				<link>https://xmdr.nl/read/objectief_verkeerd_leven</link>
				<guid isPermaLink="true">https://xmdr.nl/read/objectief_verkeerd_leven</guid>
			</item><item>
				<title>Routine</title>
				<pubDate>Tue, 12 Sep 2023 00:00:00 UTC</pubDate>
				<description><![CDATA[<h1>Routine</h1>Hijg... Hijg... Hijg... Als ik opsta, begin ik altijd met pushups tot mijn armen zeuren. Dan doe ik er nog een paar om het mijn armen af te leren. Vervolgens doe ik crunches, tot mijn maag er pijnlijk van draait. Tak... Tak... TAK... Dit volg ik op door mijn bovenarmen tegen de vensterbank te gooien, mijn schenen tegen de rand van een kast, en mijn tenen tegen de poten van mijn bed. Als je je ooit voor karate geïnteresseerd hebt, dan weet je dat de Japanners dit "kata" noemen. Vervolgens douche ik. Het liefst wissel ik dan snel tussen 15 en 51 graden, zodat mijn lichaam goed wakker schrikt. Pets... Pets... PETS... Zodra ik de kraan dicht ram, bal ik mijn vuisten en hak ik in op mijn maag. Ten slotte droog ik mezelf met het zachtste frotté, kleed ik mij in het fijnste linnen, en ontbijt ik met de knapperigste creusli. De zon begint op de komen, en de klokkensamenleving zou je graag laten geloven dat het nu vier uur is. Sommigen beweren dat melk niet goed voor je is. Anderen zeggen juist van wel. Ik zeg dat melk lekker is bij creusli.]]></description>
				<category domain="https://xmdr.nl/verhalen">verhalen</category>
				<link>https://xmdr.nl/read/routine</link>
				<guid isPermaLink="true">https://xmdr.nl/read/routine</guid>
			</item><item>
				<title>ActivityPub als interactielaag voor een blog?</title>
				<pubDate>Mon, 24 Jul 2023 00:00:00 UTC</pubDate>
				<description><![CDATA[<h1>ActivityPub als interactielaag voor een blog?</h1><p><a
href="https://en.wikipedia.org/wiki/Betteridge%27s_law_of_headlines">(Betteridge’s
law of headlines)</a></p>
<p>Vroeger kon je comments plaatsen op dit blog, maar sinds ik de
backend heb herschreven naar een enkel PHP bestand van grofweg 300
regels, bestaan comments niet meer als visueel en interactief element.
Ze bestaan alleen nog in de database, als een soort digitaal
staartbotje. Dat is toch wel jammer.</p>
<p>Dat er behoefte is aan comments, blijkt uit meerdere dingen:</p>
<ol type="1">
<li>Ik wil ze gewoon want ze zijn leuk</li>
<li>Ik krijg soms een mailtje RE: een post</li>
</ol>
<p>Maar er waren meerdere punten waar ik tegen aanliep:</p>
<ol type="1">
<li>Ik ben ook naar een VPS overgestapt waar mail niet inbegrepen was.
Ik kon dus niet makkelijk notificaties sturen als er was gereageerd op
een comment.</li>
<li>Spam blijft een ding</li>
</ol>
<p>Nu is <a href="https://joinmastodon.org/">Mastodon</a> de laatste
tijd tamelijk hip, en ik heb al eens eerder geëxperimenteerd met het
onderliggende <a href="https://activitypub.rocks/">ActivityPub
protocol</a> (Wat ik vanaf nu ga afkorten als “AP”). Kan ik Mastodon
instances het vervelende werk van user authentication en comments laten
doen, en tegelijkertijd mijn blog volgbaar maken, en elke post naadloos
integreren op de feed van mijn volgers, die allemaal op hun eigen
willekeurige en anarchistische Mastodon instances herbergen?</p>
<p>Ofwel, in de vorm van een verlanglijst:</p>
<ol type="1">
<li>Posts delen met mensen die het boeit</li>
<li>Publieke reacties op de post, vindbaar onder de post zelf</li>
<li>Zo min mogelijk spam</li>
<li>Geen hoofdpijn</li>
</ol>
<p>Mijn eerste idee was om mijn blog als AP server op te zetten met 1
gebruiker (mijzelf) die dan posts maakt, en daar dan de benodigde AP
tierelantijntjes aan toe te voegen, d.w.z. een outbox en inbox voor die
enkele “Michael” gebruiker. Mensen op een ander AP platform zoals <a
href="https://mastodon.nl">mastodon.nl</a> zouden dan “<span
class="citation" data-cites="michael">@michael</span><span
class="citation" data-cites="xmdr.nl">@xmdr.nl</span>” kunnen volgen,
alle blogposts direct op hun eigen feed op mastodon.nl zien, en daarop
kunnen reageren. Die reacties krijg ik dan d.m.v. AP in de Michael inbox
en kan ik lokaal opslaan zodat ze ook op xmdr.nl te zien zijn. Simpel
genoeg, toch? Nee!</p>
<h2 id="activitypub-is-een-twitter">ActivityPub is een Twitter</h2>
<p>AP is ontworpen voor korte content. Een “post” wordt letterlijk een
“Note” genoemd. Je hebt wel “Article”, maar dat snapt Mastodon niet, die
snapt alleen Notes. Oké, dus mijn posts kunnen nooit naadloos op een Mastodon
feed komen, maar je kan nog steeds een “Note” maken met daarin een link
naar mijn Post, en daar zou je nog steeds op kunnen commenten. Het is
totaal niet elegant, maar het zou werken. Aan de andere kant, sommige
dingen verwacht ik ook nooit op een feed te kunnen vertonen: misschien
maak ik wel een hele fancy blogpost met allerlei javascript/canvas
interactieve speeltjes, zoals je tegenkomt op de site van <a
href="https://ciechanow.ski/">Bartosz Ciechanowski</a>. Dat gaat
natuurlijk gewoon nooit overkomen. Dus ach, misschien is het ook beter
de link naar- en niet de directe inhoud zelf met AP te publiceren.</p>
<h2 id="korte-omleiding-mailto-en-de-federatie-van-e-mail">Korte
omleiding: <code>mailto:</code> en de federatie van E-mail</h2>
<p>Als je op een <code>mailto:target_account@target_server</code> URL
klikt, dan opent er een dialoog om met <em>jouw</em> e-mail client
(outlook) een mail te sturen met <em>jouw</em> e-mailaccount
(bitchboy33@) vanaf <em>jouw</em> e-mailserver (hotmail.com) naar
<em>mijn</em> e-mail account (xmdr@) op <em>mijn</em> e-mailserver
(protonmail.com), die ik vervolgens kan lezen met <em>mijn</em>
e-mailclient (thunderbird). Hoera federatie!</p>
<h2 id="activitypub-heeft-dus-geen-follow">ActivityPub heeft dus geen
<code>follow:</code></h2>
<p>Zoiets bestaat er dus niet voor AP. Er is bijvoorbeeld geen
<code>followme:@drollikker@poep.nl</code> die ervoor zorgt dat
<em>jouw</em> AP account op <em>jouw</em> AP instance (bvb <span
class="citation" data-cites="bitchboy33">@bitchboy33</span><span
class="citation" data-cites="mastodon.nl">@mastodon.nl</span>)
<em>mijn</em> AP account op <em>mijn</em> AP instance (<span
class="citation" data-cites="drollikker">@drollikker</span><span
class="citation" data-cites="poep.nl">@poep.nl</span> dus) gaat volgen.
Die naadloze integratie kan gewoon niet, het is er (nog) niet. Als je
dus “lees mijn nieuwe blogpost” berichten op <em>jouw</em> feed wil
zien, moet je moeilijk handmatig dingen in gaan stellen. Dat werkt kut
en dus gaat niemand de moeite nemen. Er is te veel <em>frictie</em>
zoals UX designers het zouden zeggen.</p>
<p>Hier, ChatGPT legt het uit:</p>
<blockquote>
<p>Ik ben een mastodon.nl gebruiker. Hoe volg ik een Actor (gebruiker)
op een andere ActivityPub (niet mastodon) server?</p>
<p><cite>Michael D. Roeleveld</cite></p>
</blockquote>
<blockquote>
<p>Als een mastodon.nl gebruiker kun je een gebruiker op een andere
ActivityPub-server volgen door het volgende proces te volgen:</p>
<ol type="1">
<li>Zoek de gebruiker op de andere ActivityPub-server op wie je wilt
volgen. Deze gebruiker moet een profiel hebben op een server die
ActivityPub ondersteunt, zoals een andere Mastodon-instantie, Pleroma,
Pixelfed, PeerTube, etc.</li>
<li>Als je het profiel van de gebruiker hebt gevonden, kopieer dan de
URL van hun profiel. Meestal heeft het profiel van een gebruiker op een
ActivityPub-server een URL die er ongeveer zo uitziet:
https://example.com/<span class="citation"
data-cites="gebruikersnaam">@gebruikersnaam</span>.</li>
<li>Ga terug naar je mastodon.nl account en zoek naar de zoekbalk of het
veld waar je nieuwe gebruikers kunt toevoegen om te volgen. Dit kan op
verschillende plaatsen zijn, afhankelijk van de specifieke
Mastodon-client die je gebruikt, maar meestal kun je een zoekopdracht
uitvoeren door op het vergrootglaspictogram te klikken of door naar een
“Ontdek” of “Profielen” sectie te gaan.</li>
<li>Plak de URL van het profiel van de gebruiker op de andere
ActivityPub-server in het zoekveld op je mastodon.nl account.</li>
<li>Klik op de knop om de gebruiker te volgen. Dit kan verschillen per
Mastodon-client, maar meestal is het een knop met de tekst “Volgen” of
een soortgelijk label.</li>
</ol>
<p>Nadat je deze stappen hebt gevolgd, zou je nu de gebruiker van de
andere ActivityPub-server moeten volgen, en hun openbare berichten
zouden op je mastodon.nl tijdlijn moeten verschijnen.</p>
<p>Houd er rekening mee dat sommige ActivityPub-servers mogelijk geen
federatie (interactie met gebruikers op andere servers) toestaan, dus
het kan zijn dat je geen interactie kunt hebben met gebruikers op
servers die geen federatie toestaan.</p>
<p><cite>ChatGPT</cite></p>
</blockquote>
<p>Check die laatste alinea dan! Al dat werk en dan <em>nog</em> kan het
zijn dat het niet <em>echt</em> werkt. Sjongejonge wat een flop.</p>
<h2 id="activitypub-is-ingewikkeld-en-niet-universeel">ActivityPub is
ingewikkeld en niet universeel</h2>
<p>Elke “grote” social medium wat op AP gebouwd is lijkt weer een ander
dialect van AP erop na te houden. Het is allemaal niet universeel
compatibel met elkaar. Dit is vrij duidelijk een probleem. Daarnaast is
het lastig om überhaupt een prototype (ofwel Minimum Viable Product
(ofwel <em>simplest possible thing that works</em>)) te maken voor een
AP-platform. Ik ga echter niet verder op deze punten in omdat het
neerkomt op vrij technisch geneuzel wat niet algemeen toepasbaar noch
interessant is, en deze post alweer lang genoeg aan het worden is.</p>
<h2 id="conclusie">Conclusie</h2>
<p>Het principe is er: wat een AP integratie op dit moment zou bieden
zijn dus comments en ik-heb-iets-geschreven-notificaties (voor mensen
met b.v.b. een Mastodon account, voor de rest niet). Maar om dan dit
blog te volgen is vervelend veel werk, en ongeveer evenveel stappen als
een RSS reader instellen, maar dan zonder garantie dat het überhaupt
werkt. Het is dus voor de groep mensen die niet aan social media doet
ook irritant als je een comment wil maken, en dan vervolgens een account
moet maken op een hele andere site die je anders niet gaat gebruiken. Ik
voorzie ook veel debugging met APIs van externe partijen wat gewoon
altijd vervelend is, dat geeft mij veel hoofdpijn. Behalve comments kan
alles wat ik wil nu al met de RSS feed en het e-mailadres die ik
publiceer.</p>
<p>Mastodon en dergelijke zijn dus leuk als je op zoek bent naar een
twitter-vervanger om elke uwer scheet naar te uploaden (inclusief <a
href="https://mastodon.social/@davew/110753813670734170">oprechte
<em>shit takes</em> over AI</a>) en die van anderen stevig te inhaleren,
maar het is niet redelijkerwijs bruikbaar als werkelijk gefedereerd
lees-, interactie-, en publicatieplatform voor langere blogposts.</p>
]]></description>
				<category domain="https://xmdr.nl/blog">blog</category>
				<link>https://xmdr.nl/read/activitypub_interactie_blog</link>
				<guid isPermaLink="true">https://xmdr.nl/read/activitypub_interactie_blog</guid>
			</item></channel>
</rss>