<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Michael Färber</title>
    <description>Logik, Musik, Fahrrad, Sprachen.
</description>
    <link>http://gedenkt.at/</link>
    <atom:link href="http://gedenkt.at/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 17 Aug 2025 07:59:25 +0000</pubDate>
    <lastBuildDate>Sun, 17 Aug 2025 07:59:25 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>R.I.P. Gilles Dowek</title>
        <description>&lt;p&gt;Le 21 juillet 2025, &lt;a href=&quot;https://fr.wikipedia.org/wiki/Gilles_Dowek&quot;&gt;Gilles Dowek&lt;/a&gt; est décédé.
J’ai eu l’honneur de travailler avec lui pendant quelques mois
dans son groupe de travail, DEDUCTEAM,
à partir de 2019 jusqu’au début de la pandémie Corona.
Voici quelques mots pour cette triste occasion.&lt;/p&gt;

&lt;p&gt;Gilles Dowek était un chercheur et un homme exceptionnel.
Parmi tous les chefs que j’avais jusqu’à maintenant, c’était le meilleur.
C’est pourquoi je suis attristé qu’il a dû nous quitter à seulement 58 ans.
Il aurait pu encore faire tellement plus.&lt;/p&gt;

&lt;p&gt;Gilles exposait une énorme positivité qui se voyait dans tout ce qu’il faisait.
Il portait souvent un sourire très coquin,
et je ne me souviens d’aucune occasion où je l’ai vu fâché où agacé.
Il était très “zen”.&lt;/p&gt;

&lt;p&gt;Je le voyais le plus souvent lors de nos déjeuners en groupe au Resto’U,
qui étaient toujours très animés par la politique.
Dans ces occasions, il nous racontait quelque fois de
son engagement pour l’enseignement de l’informatique,
où on voyait qu’il ne se contentait pas d’être un professeur à l’université,
mais qu’il avait des ambitions d’améliorer aussi les conditions politiques.
Malgré le fait qu’il avait manifestement des contacts avec des gens très importants,
il restait toujours très modeste en parlant avec nous.
Il nous attribuait autant d’attention qu’à un ministre d’état.&lt;/p&gt;

&lt;p&gt;Quand je relis ses courriels, je remarque une très grande proportion de mots positifs:
Souvent, ses messages commençaient avec “Les amiEs”,
pour finir avec “Amitiés” ou “Amicalement”.
Entre ces lignes, il écrivait très, très souvent “Super” et “Merci”.
Une incroyable gentillesse émanait des ses paroles et de ses regards.
Je ne me rappelle pas de lui d’une seule reproche, et pas d’un ordre.
Il nous proposait des choses, mais il acceptait un “non”, et pouvait même en sourire.
Il a toujours montré un grand respect pour moi, et en échange,
je lui gardais aussi toujours un énorme respect.&lt;/p&gt;

&lt;p&gt;Je me rappelle d’une occasion où il a pris rendez-vous avec moi dans son bureau,
pour me convaincre de rester dans la recherche.
Il m’a dit quelque chose du style qu’il me pensait apte pour cela.
Ça m’a touché, car je sentais qu’il disait pas ça pour son propre profit,
mais qu’il était sincèrement intéressé par moi et mon destin.
Ce genre d’encouragement et intérêt est rare, et autant plus précieux.&lt;/p&gt;

&lt;p&gt;Gilles était un chercheur et chef exceptionnel.
Il savait où il fallait lâcher prise, et
il savait manier chacun et chacune à sa manière pour donner de son mieux.
Et ça voulait aussi dire qu’il laissait du temps si on en avait besoin.
Par exemple, le projet pour lequel j’étais engagé originalement
ne m’a pas autant inspiré,
et j’ai commencé à analyser et chercher à comprendre
le logiciel principal que Gilles nous a légué, c’est-à-dire Dedukti.
Quelqu’un d’autre aurait peut-être empêché ma divergence,
mais Gilles m’a laissé faire à mon rythme, même si pendant longtemps,
mon travail aurait peut-être pas forcément gagné le prédicat “productif”.
En échange, ma diversion a produit un joli article, et
elle forme la base de mon travail actuel, cinq ans plus tard.
Quand j’ai présenté mon article, Gilles a fait une petite remarque
à propos de la distinction entre la mémoire à court terme et long terme.
Cette remarque a germé dans ma tête, et plus tard, elle a porté des fruits,
en inspirant toute seule une toute nouvelle piste de ma recherche,
qui a donné naissance à un autre très joli article.
Avec peu de mots, il avait une influence profonde.&lt;/p&gt;

&lt;p&gt;Une de mes anecdotes favoris avec Gilles est la suivante:
Gilles voulait qu’un doctorant fasse un site web pour son projet Logipedia.
Mais le doctorant disait toujours “oui, oui” à ces demandes, sans que jamais quelque chose en suivait.
Du coup, un jour, Gilles a pris toute sa journée (malgré son planning très chargé)
et s’est assis à côté du doctorant, en le regardant faire le travail demandé.
Et ainsi, le site web était complété.&lt;/p&gt;

&lt;p&gt;Je voudrais remercier Gilles pour sa profonde humanité et son humeur.
Pour l’atmosphère d’amitié qu’il a fait régner dans son laboratoire,
et pour sa compréhension et sa patience.
Pour son soutien et pour son œuvre.
Pour son engagement et son attention pour autrui.
Il est un phare et un modèle pour moi.&lt;/p&gt;

&lt;p&gt;Merci, Gilles, c’était super avec toi !&lt;/p&gt;

&lt;p&gt;Amicalement,&lt;br /&gt;
Michael&lt;/p&gt;
</description>
        <pubDate>Thu, 24 Jul 2025 00:00:00 +0000</pubDate>
        <link>http://gedenkt.at/blog/rip-gilles-dowek/</link>
        <guid isPermaLink="true">http://gedenkt.at/blog/rip-gilles-dowek/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>The `string_chars` problem and how internal references solve it</title>
        <description>&lt;p&gt;In this post, I write about a common pain point that I encountered
when working with Rust’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterator&lt;/code&gt; trait, which can be demonstrated by
a simple example that I call the “&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_chars&lt;/code&gt; problem”.
I then explore the potential of Niko Matsakis’s “&lt;a href=&quot;https://smallcultfollowing.com/babysteps/blog/2024/06/02/the-borrow-checker-within/#step-4-internal-references&quot;&gt;internal references&lt;/a&gt;” proposal
to remedy this problem.&lt;/p&gt;

&lt;p&gt;But first, I’ll start with my experiences with LLMs to deal with hard programming problems, which is what got the ball rolling for this post.&lt;/p&gt;

&lt;h2 id=&quot;llm-experiments&quot;&gt;LLM Experiments&lt;/h2&gt;

&lt;p&gt;This post was motivated by a conversation with my LLM-loving colleagues
about my experiences with LLMs.
After that conversation, I gave my colleagues a little live demo of how
LLMs fail to address seemingly very simple programming tasks.
The game goes as follows: You come up with a prompt à la:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Write me a Rust function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn f(...) -&amp;gt; ...&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The LLM wins if and only if
it comes up with code that compiles or
if it shows that the function cannot be implemented.&lt;sup id=&quot;fnref:llm-game&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:llm-game&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;The first example I tried was:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Write me a Rust function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn&amp;lt;T, U&amp;gt;(x: T) -&amp;gt; U&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The LLM (ChatGPT in my case) answered:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In Rust, writing a function with the signature &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn&amp;lt;T, U&amp;gt;(x: T) -&amp;gt; U&lt;/code&gt; is not possible without additional constraints.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It then explains quite thoroughly why this is not possible, and
how to modify the original function signature to make it implementable.
Fair enough. The LLM wins this round.&lt;/p&gt;

&lt;h3 id=&quot;the-string_chars-problem&quot;&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_chars&lt;/code&gt; Problem&lt;/h3&gt;

&lt;p&gt;Let’s try another one, which I call the “&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_chars&lt;/code&gt; problem”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Write me a Rust function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn string_chars(s: String) -&amp;gt; impl Iterator&amp;lt;Item = char&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ChatGPT answers the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fn string_chars(s: String) -&amp;gt; impl Iterator&amp;lt;Item = char&amp;gt; {
    s.chars()
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The problem is, &lt;a href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=bc2c2ad060b279a8cea21c70cc9a9071&quot;&gt;it does not compile&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;error[E0597]: `s` does not live long enough
 --&amp;gt; src/main.rs:2:5
  |
1 | fn string_chars(s: String) -&amp;gt; impl Iterator&amp;lt;Item = char&amp;gt; {
  |                 - binding `s` declared here
2 |     s.chars()
  |     ^--------
  |     |
  |     borrowed value does not live long enough
  |     opaque type requires that `s` is borrowed for `&apos;static`
3 | }
  | - `s` dropped here while still borrowed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When telling ChatGPT “This does not compile.”, it comes up with the following response:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You’re absolutely right — and thank you for pointing that out.&lt;/p&gt;

  &lt;p&gt;The problem is that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s.chars()&lt;/code&gt; borrows the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String&lt;/code&gt;, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt; is moved into the function, and the returned iterator would need to capture &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt; by value (i.e. own it), which &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chars()&lt;/code&gt; alone doesn’t do. This leads to a lifetime issue: the returned iterator would reference &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt;, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt; is dropped at the end of the function.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds … not too bad.&lt;/p&gt;

&lt;p&gt;What follows is hilarious:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;✅ Working version:&lt;/p&gt;

  &lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;string_chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.into_chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;Wait — actually, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String::into_chars()&lt;/code&gt; doesn’t exist.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At least, it is honest! Although it would be nice if it would think before it writes.
But that would presuppose that these language models can actually think.&lt;/p&gt;

&lt;p&gt;ChatGPT’s next attempt is fun too:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;So instead, we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::iter::once&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flat_map&lt;/code&gt;:&lt;/p&gt;

  &lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;string_chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;once&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.flat_map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;You know that often, when I read these solutions, my first reaction is like
“oh, this could actually work”.
Until I’m quickly persuaded otherwise by the compiler.
More ChatGPT output:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;✅ Alternative with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Box&amp;lt;dyn Iterator&amp;gt;&lt;/code&gt; (trait object):&lt;/p&gt;

  &lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;string_chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;dyn&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;p&gt;This version avoids &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;impl Trait&lt;/code&gt; and returns a boxed trait object instead, which works because the boxed iterator can own the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String&lt;/code&gt; via closure capture.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To spoil it: &lt;em&gt;None&lt;/em&gt; of the presented solutions even compiles.
The LLM loses the round.
I, for one, welcome our new AI overlords. ✅&lt;/p&gt;

&lt;p&gt;I find this highly unfortunate.
I’m not talking about the lousy LLM performance here.&lt;sup id=&quot;fnref:llm&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:llm&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
I’m talking about the fact that there is no way to write a proper
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn string_chars(s: String) -&amp;gt; impl Iterator&amp;lt;Item = char&amp;gt;&lt;/code&gt; function
(without unsafe Rust or external libraries, see the &lt;a href=&quot;#ps&quot;&gt;end of this post&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id=&quot;generalising-the-string_chars-problem&quot;&gt;Generalising the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_chars&lt;/code&gt; Problem&lt;/h2&gt;

&lt;p&gt;We can generalise the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_chars&lt;/code&gt; problem.
The underlying issue occurs whenever you have
a function that produces an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterator&lt;/code&gt; from a reference &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;T&lt;/code&gt;, and
you call that function with an owned value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; and return the resulting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterator&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;&apos;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;&apos;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&apos;a&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// just something that makes this code compile&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;core&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This triggers the same dreaded &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;error[E0597]: x does not live long enough&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I have encountered this issue a &lt;em&gt;lot&lt;/em&gt; of times during the last years.
It probably has to do with the fact that I am writing a program called
&lt;a href=&quot;https://github.com/01mf02/jaq&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jaq&lt;/code&gt;&lt;/a&gt;
which is very heavily based on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterator&lt;/code&gt;s.
In particular, jaq consists of many functions that have the same shape as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;g&lt;/code&gt; above:
Take an owned value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;, and return an iterator of values &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U&lt;/code&gt;.
This pattern is so deeply built into jaq’s architecture that I cannot just write
my functions more akin to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt; above (take a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;T&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;).
Being unable to call iterator functions that take &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;T&lt;/code&gt; from
iterator functions that take &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; is very frustrating.&lt;/p&gt;

&lt;h2 id=&quot;type-power&quot;&gt;Type Power&lt;/h2&gt;

&lt;p&gt;This issue violates an implicit assumption of mine about the power of types.
In my mental model, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T &amp;gt; &amp;amp;mut T &amp;gt; &amp;amp;T&lt;/code&gt;.
In other words,
when you have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt;, you can do everything with it that you can do with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;mut T&lt;/code&gt;, and
when you have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;mut T&lt;/code&gt;, you can do everything with it that you can do with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;T&lt;/code&gt;.
However, in this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterator&lt;/code&gt; scenario, we can see that
having a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; does not automatically enable to do the same things that you can do with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;T&lt;/code&gt;.
Sometimes, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; is worse than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;T&lt;/code&gt;!
And I find that very confusing.&lt;/p&gt;

&lt;h2 id=&quot;workarounds&quot;&gt;Workarounds&lt;/h2&gt;

&lt;p&gt;When I saw people asking about similar &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterator&lt;/code&gt; problems on online forums,
chances are high that somebody will point out that you can do this:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;string_chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.collect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.into_iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this particular case, that “works”.
But it is a really poor solution, because it has to allocate memory.
And in some scenarios that are more complex than this toy example,
you cannot just &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.collect().into_iter()&lt;/code&gt; your way out:
For example, the underlying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterator&lt;/code&gt; might yield infinitely many values.
Or the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterator&lt;/code&gt; might yield values where each individual value is small enough to fit in memory, but all values together do not fit into RAM.
In these cases, it’s game over.&lt;/p&gt;

&lt;p&gt;Anyway, I hope that you agree with me that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.collect().into_iter()&lt;/code&gt;
is a crutch — it &lt;em&gt;might&lt;/em&gt; get you where you want, but it’s not elegant, and
good luck hiking up a mountain with it.&lt;/p&gt;

&lt;h2 id=&quot;internal-references&quot;&gt;Internal references&lt;/h2&gt;

&lt;p&gt;This brings me to one of my most anticipated developments in the Rust language: &lt;a href=&quot;https://smallcultfollowing.com/babysteps/blog/2024/06/02/the-borrow-checker-within/#step-4-internal-references&quot;&gt;internal references&lt;/a&gt;.
Niko Matsakis starts his blog post’s section about them with the sentence:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Rust today cannot support structs whose fields refer to data owned by another.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He then gives an example of a hypothetic Rust syntax where struct fields &lt;em&gt;can&lt;/em&gt; refer to data:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;&apos;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.text&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;&apos;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.text&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;&apos;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.text&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now where’s the connection to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterator&lt;/code&gt; problem I outlined above?
Very simple: At some point, I wondered whether I could not make a struct
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StringChars&lt;/code&gt; which I could construct from a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String&lt;/code&gt; and on which I could then
implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Iterator&lt;/code&gt; manually myself.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StringChars&lt;/code&gt; would also need to hold on to a
&lt;a href=&quot;https://doc.rust-lang.org/core/str/struct.Chars.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;core::str::Chars&lt;/code&gt;&lt;/a&gt;
(which is returned by &lt;a href=&quot;https://doc.rust-lang.org/core/primitive.str.html#method.chars&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str::chars&lt;/code&gt;&lt;/a&gt;),
and return its output whenever we call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StringChars::next()&lt;/code&gt;.
How would this struct look like?&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StringChars&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;core&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But this does not work:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;E0106&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;missing&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lifetime&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;specifier&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.rs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;core&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;                      &lt;span class=&quot;o&quot;&gt;^^^^^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;named&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lifetime&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So what is the lifetime that we have to give to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Chars&lt;/code&gt; here?
Enter internal references:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StringChars&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;core&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Chars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;&apos;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here, we say that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iter&lt;/code&gt; lives as long as our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self.s&lt;/code&gt;.
That would solve the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_chars&lt;/code&gt; problem!&lt;/p&gt;

&lt;p&gt;My dream is that one day, we could even write the original “solution”, and
Rust would create something like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StringChars&lt;/code&gt; under the hood automatically:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;string_chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I would love to see built-in internal references become a reality in Rust.
Rust’s lack of internal references has already struck me as very awkward when I learnt the language,
and since then, I have continued to hit cases like the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_chars&lt;/code&gt; problem time and again.
These problems are especially hard to solve for newcomers, because
it is not clear from the naive definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_chars&lt;/code&gt; that
the underlying problem is that self-referential data is not allowed.
For that reason, internal references are clearly my #1 item on my wish list for Rust.&lt;/p&gt;

&lt;h2 id=&quot;ps&quot;&gt;Post Scriptum: Getting Internal References Today&lt;/h2&gt;

&lt;p&gt;After having written the rest of this post, I found
&lt;a href=&quot;https://stackoverflow.com/a/32300133&quot;&gt;this very exhaustive answer&lt;/a&gt;, which
links a few more self-referential struct libraries than Niko does.
In particular, I tried &lt;a href=&quot;https://crates.io/crates/ouroboros&quot;&gt;ouroboros&lt;/a&gt;, but then
I quickly transitioned to &lt;a href=&quot;https://crates.io/crates/self_cell&quot;&gt;self_cell&lt;/a&gt;,
because it has significantly fewer dependencies.&lt;/p&gt;

&lt;p&gt;Lo and behold, here is a solution to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_chars&lt;/code&gt; problem in today’s Rust:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;self_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Chars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;&apos;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;core&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Chars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;&apos;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;self_cell!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StringChars&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;owner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;nd&quot;&gt;#[not_covariant]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dependent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Iterator&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StringChars&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.with_dependent_mut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_owner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;string_chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;StringChars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chars&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;string_chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hi!&quot;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.to_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chars&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;&apos;H&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chars&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;&apos;i&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chars&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;&apos;!&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In my opinion, &lt;em&gt;this&lt;/em&gt; is the answer that an LLM should have given me.
But I cannot blame it;
the link between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string_chars&lt;/code&gt; and self-referential structs is really not obvious.&lt;/p&gt;

&lt;p&gt;Still, it would be nice if there was a more “built-in” way to do all this …&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:llm-game&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;We are not even talking about writing code that actually “works”, just about code that actually compiles. Rust is particularly suited for this game, because the type system is so expressive, so we can actually express many cool properties in the function signature that we could not do in, say, Python. &lt;a href=&quot;#fnref:llm-game&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:llm&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;In my humble opinion, the bad LLM performance is to be expected, because today’s LLMs do not have access to programming tools, such as a Rust compiler. Today’s LLMs only learn from what human beings have written about programming problems — they cannot perform programming experiments themselves. Would you expect a medicine student who has read all existing medical literature, but who has never operated on a patient himself, to come up with a novel operation technique? And would you like to be the lucky first patient that this novel technique is tried on? &lt;a href=&quot;#fnref:llm&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 17 Jul 2025 00:00:00 +0000</pubDate>
        <link>http://gedenkt.at/blog/string-chars/</link>
        <guid isPermaLink="true">http://gedenkt.at/blog/string-chars/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>A Data Bridge from Rust to Haskell</title>
        <description>&lt;p&gt;This post describes a method to serialise a complex Rust data structure and
to deserialise it to a corresponding Haskell data structure,
without any external dependencies and with only minimal boilerplate.&lt;/p&gt;

&lt;h2 id=&quot;problem--research&quot;&gt;Problem &amp;amp; Research&lt;/h2&gt;

&lt;p&gt;Recently, I wanted to process some data (jq programs) in a Haskell program.
I had previously written a jq parser in Rust, so my first approach was to write a small jq parser in Haskell. However, I quickly found myself bored and annoyed to write one more parser for the same format.&lt;/p&gt;

&lt;p&gt;Thus I started to think about using my Rust-written jq parser from my Haskell program. I would somehow need to serialise the output of my parser into some intermediate format, then deserialise from that format to a data structure in Haskell.
I additionally had a few constraints: In particular, I did not want to use any external dependencies on the Haskell side, because I had made some painful experiences with Haskell’s package management from years ago. Furthermore, I also did not want to add any new dependencies to my Rust code. In addition, if possible, I wanted to write a minimum of code for this (de-)serialisation task.&lt;/p&gt;

&lt;p&gt;At first, I found that GHC (Haskell’s main compiler) ships a &lt;a href=&quot;https://hackage.haskell.org/package/binary&quot;&gt;binary en-/decoding package&lt;/a&gt;. While that initially looked quite promising, I decided against using it because this library has a function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;putStringUtf8&lt;/code&gt; to &lt;em&gt;encode&lt;/em&gt; a string, but it does not have a corresponding function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getStringUtf8&lt;/code&gt; to &lt;em&gt;decode&lt;/em&gt; a string. Given that strings are one of the data structures I need to encode the most and I did not find easily how to implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getStringUtf8&lt;/code&gt; myself, I reconsidered my choice of using this library.&lt;/p&gt;

&lt;p&gt;Searching a bit more, I found Haskell’s &lt;a href=&quot;https://hackage.haskell.org/package/base/docs/Text-Read.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Read&lt;/code&gt;&lt;/a&gt; class. This allows you to automatically generate a parser for your Haskell data types. Because writing data parsers is generally much harder than writing data printers, I figured that I could simply write data on the Rust side that can then be read by Haskell’s automatically generated parser.&lt;/p&gt;

&lt;p&gt;However, it gets even better: I found out that if I stick to a certain subset of data structures on both the Haskell and the Rust side, then I can automatically generate a printer on the Rust side using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#[derive(Debug)]&lt;/code&gt; and automatically generate a parser on the Haskell side using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deriving Read&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I will now write give you some example code that shows how to automatically
(de-)serialise data from Rust to Haskell.
You can find the full source code in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ujq&lt;/code&gt; folder of
&lt;a href=&quot;https://github.com/01mf02/jq-lang-spec/&quot;&gt;this repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;serialisation&quot;&gt;Serialisation&lt;/h2&gt;

&lt;p&gt;Consider the following Rust code:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;#[derive(Debug)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Term&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Pipe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pattern&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;#[derive(Debug)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Pattern&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(I use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S&lt;/code&gt; as a type parameter on the Rust side for unrelated reasons;
just pretend that I am using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String&lt;/code&gt; in place for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S&lt;/code&gt; everywhere.)&lt;/p&gt;

&lt;p&gt;When printing a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tm: Term&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;println!(&quot;{tm:?}&quot;)&lt;/code&gt;, this yields something like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Arr(Some(Pipe(Id, Some(Arr([Var(&quot;$x&quot;), Var(&quot;$y&quot;)])), Str(&quot;a&quot;))))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;deserialisation&quot;&gt;Deserialisation&lt;/h2&gt;

&lt;p&gt;Now to the Haskell side: How to deserialise a term that was output via Rust’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Debug&lt;/code&gt;?
Let us first define data structures in Haskell analogous to the Rust side:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Term&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;Id&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Pipe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Pattern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kr&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Pattern&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Pattern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
  &lt;span class=&quot;kr&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here, we have our first problem: In Rust, we can define in the same module
multiple data types with constructors that have the same name;
in our example, we have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Term::Arr&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pattern::Arr&lt;/code&gt;.
This is not possible in Haskell; therefore,
we cannot put &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Term&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pattern&lt;/code&gt; into the same file.&lt;/p&gt;

&lt;p&gt;So we have to move &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pattern&lt;/code&gt; to a different Haskell module and
import that from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Term&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;Note that I used some slightly non-idiomatic Haskell here:
In Haskell, you would rather write
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pipe Term (Option Pattern) Term&lt;/code&gt; instead of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pipe(Term, Option Pattern, Term)&lt;/code&gt;.
However, when we use the more idiomatic version, the auto-generated
parser cannot parse terms of the shape &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pipe(a, b, c)&lt;/code&gt;, only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pipe a b c&lt;/code&gt;.
Because Rust outputs terms of the shape &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pipe(a, b, c)&lt;/code&gt;,
we use the less idiomatic version here.&lt;/p&gt;

&lt;p&gt;Next, you might notice that I used an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Option&lt;/code&gt; type on the Haskell side,
analogous to the Rust &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Option&lt;/code&gt; type — but Haskell does not have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Option&lt;/code&gt;.
Haskell has &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Maybe&lt;/code&gt;, baby.
No big deal.
I defined an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Option&lt;/code&gt; type in Haskell the same way as in Rust, and
made a helper function to convert from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Option&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Maybe&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;kr&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;toMaybe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;toMaybe&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Nothing&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;toMaybe&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;putting-things-together&quot;&gt;Putting things together&lt;/h2&gt;

&lt;p&gt;I made a little shell script that passes its first argument to the Rust parser.
The Rust parser then writes its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Debug&lt;/code&gt; output on stdout, from where
the Haskell program picks it up:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;echo &quot;$1&quot; | ./rust-parser | ./haskell-reader
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The Rust part reads from stdin, runs the parser, and serialises its output:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;read_to_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{tm:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The Haskell part captures the serialised Rust data on stdin and
parses it to the corresponding Haskell &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Term&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;main :: IO ()
main = do
  stdin &amp;lt;- getContents
  let term :: Term = read stdin
  print term
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And that just works nicely!&lt;/p&gt;

&lt;h2 id=&quot;restrictions&quot;&gt;Restrictions&lt;/h2&gt;

&lt;p&gt;On the Rust side, I have something like this:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Def&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I tried to make a Haskell counterpart for this as follows:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Def&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Def&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, Haskell uses a different syntax than Rust to create values of such types:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;-- Haskell
Def {name = &quot;f&quot;, args = []}
// Rust
Def {name: &quot;f&quot;, args: []}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That means that Haskell’s auto-generated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Read&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Def&lt;/code&gt; cannot parse
the output of Rust’s auto-generated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Debug&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Def&lt;/code&gt;.
Because I did not want to change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Def&lt;/code&gt; type on the Rust side,
I did simply create a custom &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Debug&lt;/code&gt; implementation for it:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Debug&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Def&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Formatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nd&quot;&gt;write!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;({:?}, {:?})&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(That was the only change that I made to the Rust code base!)
On the Haskell side, I simply introduced:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Def&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Alternatively, I could have written&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Def&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;on the Rust side and&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Def&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;on the Haskell side.&lt;/p&gt;

&lt;p&gt;I noticed that Rust also has a slightly different way to print Unicode characters.
In particular, it prints stuff like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\u{1}&lt;/code&gt;, which Haskell does not understand.
I do not expect such characters in my data, so I do not care about this.&lt;/p&gt;
</description>
        <pubDate>Tue, 24 Jun 2025 00:00:00 +0000</pubDate>
        <link>http://gedenkt.at/blog/data-bridge-rust-haskell/</link>
        <guid isPermaLink="true">http://gedenkt.at/blog/data-bridge-rust-haskell/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Five Years of Rust</title>
        <description>&lt;p&gt;About five years ago, I made my first steps with the programming language Rust.
This recapitulates my Rust journey since then.&lt;/p&gt;

&lt;p&gt;In late 2019, I had just started my postdoc with Deducteam at ENS Paris-Saclay.&lt;sup id=&quot;fnref:ens&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:ens&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
I was to work with a tool called &lt;a href=&quot;https://deducteam.github.io/&quot;&gt;Dedukti&lt;/a&gt;,
which is a so-called proof checker.
Quickly, I got sidestepped from working &lt;em&gt;with&lt;/em&gt; Dedukti to working &lt;em&gt;on&lt;/em&gt; Dedukti.
Dedukti is written in OCaml, and at that time, I was a Haskell adept.
After a few discussions with my collegues, I wanted to try whether I could rewrite
a part of Dedukti in Haskell and achieve better performance than in OCaml.
This was a &lt;a href=&quot;https://github.com/01mf02/kontroli-hs&quot;&gt;short voyage&lt;/a&gt; full of pain:
Although I believe that I was not a bad Haskell programmer,
using it I struggled to barely match the speed of OCaml.
At that point, I was disappointed by my then favourite programming language.
A bit of research later, I found out about Rust and gave it a shot.&lt;sup id=&quot;fnref:rust-139&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:rust-139&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
After about one week of learning Rust from zero, I had a working parser for
Dedukti whose performance exceeded all my previous Haskell efforts,
and which started to match the performance of Dedukti.
This was the beginning of an amazing journey for me.&lt;/p&gt;

&lt;p&gt;In the following months, I reimplemented more and more parts of Dedukti in Rust,
which gave rise to the proof checker that I called &lt;a href=&quot;https://github.com/01mf02/kontroli-rs&quot;&gt;Kontroli&lt;/a&gt;.
At this point, I have to thank my then-supervisors Gilles Dowek and Frédéric Blanqui
for having been so open-minded and tolerant towards these efforts of mine —
I’m not that sure that they were initially so happy with my diverging so much
from my original agenda. :)
At a certain point, my proof checker was a bit faster than Dedukti.
That was when my colleagues tried to convince me to make Kontroli multi-threaded,
given Rust’s reputation for high-performance concurrency.
I was reluctant at first, because I had vague memories of
my previous concurrency adventures
having been rather painful (in C, C++, and Java) or
having gained relatively little performance (Haskell).
In the end, I gave in, and after a few weeks of work
(the first Covid lockdown in France had just started!),
I had a fully functional concurrent proof checker
(&lt;a href=&quot;https://github.com/01mf02/kontroli-rs/commit/6edf1baef1843678e2fb00a4d7b07e8cbe96c864&quot;&gt;commit&lt;/a&gt;).
The first version still had some bottlenecks,
but a second version removed these and allowed using the same code for
both single-threaded and multi-threaded operation without overhead.
That unlocked significant performance gains,
reducing runtime by up to 8x compared to Dedukti!
I managed to publish &lt;a href=&quot;https://doi.org/10.1145/3573105.3575686&quot;&gt;two papers&lt;/a&gt;
about this engineering feat.&lt;/p&gt;

&lt;p&gt;In 2020, I started a postdoc in Amsterdam.
My originally planned work was severely compromised by the fact that
due to Covid, all my colleagues (including my supervisor)
were in home-office, some even from abroad.
So my natural tendency to diverge from originally planned agendas kicked in again,
when I was just setting out to analyse some JSON data.
After some language research, I found the jq language to manipulate JSON data,
but I was flabbergasted when I found that starting jq took a whopping 50 milliseconds,
which limited the rate of files that I was able to process to 20/second!
However, I regularly had several thousands of files to process,
and I did not want to wait for several minutes each time.
That was when I repeated my Dedukti experiment:
How fast could I make a tiny clone of jq that could allow me to perform my research?
Five days later, I had a functional prototype
(see &lt;a href=&quot;https://github.com/01mf02/adam-notes?tab=readme-ov-file#2020-12-04&quot;&gt;research journal&lt;/a&gt;)
that had the performance that I wished for.
In the next months, I sporadically hacked on this prototype
that I called &lt;a href=&quot;https://github.com/01mf02/jaq&quot;&gt;jaq&lt;/a&gt;,
and built more and more of jq’s functionality into it.
At some point, I &lt;a href=&quot;https://www.reddit.com/r/rust/comments/ucyq01/announcing_jaq_a_jq_clone_focussing_on/&quot;&gt;wrote about it on the Rust Reddit&lt;/a&gt;,
at which point the popularity of the project skyrocketed.
I had never before created such an impact with another piece of work before,
and I was quite happy about this.&lt;/p&gt;

&lt;p&gt;After finishing my postdoc, I was unemployed for about one year,
during which I continued my work on jaq in my free time.
I looked for interesting programming jobs, but at that point,
the only jobs in my home town (&lt;a href=&quot;https://en.wikipedia.org/wiki/Innsbruck&quot;&gt;Innsbruck&lt;/a&gt;) used
languages like C/C++/Java/Python, and I could not bring myself to work with these,
because these languages felt to me like a too large step back from Rust.
Eventually, I heard about the &lt;a href=&quot;https://nlnet.nl/&quot;&gt;NLnet Foundation&lt;/a&gt;,
which sponsors open source projects.
I applied and got &lt;a href=&quot;https://nlnet.nl/project/jaq/&quot;&gt;funded to work on jaq&lt;/a&gt; for several months.
I am incredibly grateful to NLnet for having granted me this opportunity,
because I love to work for the common good
(by providing my software to the public for free),
yet at the end of the day, I have to pay for my food and rent like everyone else.&lt;/p&gt;

&lt;p&gt;As part of my NLnet project, I wrote a
&lt;a href=&quot;https://github.com/01mf02/jq-lang-spec/&quot;&gt;document&lt;/a&gt; using &lt;a href=&quot;https://typst.app/&quot;&gt;Typst&lt;/a&gt;,
a typesetting program written in Rust that aims to be a
more user-friendly and performant alternative to LaTeX.
However, the NLnet people were concerned about Typst not being able to export to HTML,
which they felt was the right format for my document to be published in.
I believe that I jokingly told them that if Typst could not still not export to HTML
by the time my NLnet grant was over, I could just
apply for another NLnet grant to implement this functionality myself.
And that is what eventually happened.
In December 2024, I started working on
&lt;a href=&quot;https://nlnet.nl/project/Typst-HTML/&quot;&gt;HTML export from Typst&lt;/a&gt;,
which is a functionality that many people (including myself)
have yearned to use since a long time already.&lt;/p&gt;

&lt;p&gt;Rust has accompanied my programming life since five years, and I
am very grateful to the Rust community for having created this language.
I still enjoy working with Rust every day, and for me,
it comes very close to being a perfect programming language.
Before Rust, I had mainly worked with languages that were
fast, but unsafe (C/C++), or
safe, but slow (Haskell).&lt;sup id=&quot;fnref:ocaml&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:ocaml&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
Rust not only achieves the trifecta of enabling programs that are at the same time
fast, safe, and concurrent.
It has also reconciled two worlds that previously seemed unreconcilable to
me, namely the worlds of imperative and functional programming.
This means that it has led functional programmers like me to embrace imperative programming, and
I hope that it will continue to lure imperative programmers into functional programming.
All for the benefit of creating fast, safe, and beautiful programs.&lt;/p&gt;

&lt;p&gt;To many more years of Rust!&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:ens&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;ENS Paris-Saclay was actually located neither in Paris nor in Saclay, but in a cute suburb of Paris called Cachan, to which I cycled every day from Paris. &lt;a href=&quot;#fnref:ens&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:rust-139&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;At that time, by the way, the current Rust version was &lt;a href=&quot;https://blog.rust-lang.org/2019/11/07/Rust-1.39.0.html&quot;&gt;1.39&lt;/a&gt;, which stabilised &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async fn&lt;/code&gt;s. One of the Rust features I basically never use. &lt;a href=&quot;#fnref:rust-139&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:ocaml&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;OCaml strikes an interesting middle ground, being a relatively fast and safe language. However, it makes the use of global mutable variables so easy that I found many OCaml programs to use this feature quite extensively, which led to extensive hair loss on my side. &lt;a href=&quot;#fnref:ocaml&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Mon, 09 Dec 2024 00:00:00 +0000</pubDate>
        <link>http://gedenkt.at/blog/five-years-of-rust/</link>
        <guid isPermaLink="true">http://gedenkt.at/blog/five-years-of-rust/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Flamegraphs for recursive functions in Rust</title>
        <description>&lt;p&gt;Some time ago, I tried to create a flamegraph for a program of mine,
to find out which functions take which share of the program runtime.
However, I found that the flamegraph generated by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cargo flamegraph&lt;/code&gt;
was completely unusable for me.
This was because my program used two mutually recursive functions
(functions that call each other repeatedly).
In this post, I will demonstrate the problem and how to solve it.&lt;/p&gt;

&lt;p&gt;Let us make a new Rust project called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even-odd&lt;/code&gt; by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cargo new even-odd&lt;/code&gt;.
Then change to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even-odd&lt;/code&gt; directory and write the following to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/main.rs&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;even&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;odd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;odd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;even&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;even&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100_000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is a toy benchmark that contains two mutually recursive functions, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odd&lt;/code&gt;.
(You can see that because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even&lt;/code&gt; calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odd&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odd&lt;/code&gt; calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;Normally, you build code for good performance in release mode, by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cargo build --release&lt;/code&gt;.
However, when building this toy benchmark in release mode,
the compiler realises that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even(100_000)&lt;/code&gt; evaluates to true,
so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even(100_000)&lt;/code&gt; is actually not evaluated at run-time.
Therefore, we are going to build this benchmark in dev mode, by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cargo build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, how to create a flamegraph?
I installed the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flamegraph&lt;/code&gt; crate following
&lt;a href=&quot;https://crates.io/crates/flamegraph&quot;&gt;its instructions&lt;/a&gt;.
Once this is done, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cargo flamegraph&lt;/code&gt; builds and runs your program with profiling enabled.
However, watch out because unlike &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cargo run&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cargo flamegraph&lt;/code&gt; builds by default in release mode.
To have it build in dev mode (as needed here), use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cargo flamegraph --dev&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To collect performance statistics, you will likely need to run the following
if you are on a Linux system:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo sysctl -w kernel.perf_event_paranoid=1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(Source: &lt;a href=&quot;https://superuser.com/a/980757&quot;&gt;https://superuser.com/a/980757&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Finally, we should be getting a result in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flamegraph.svg&lt;/code&gt; that looks as follows:&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2022-04-15-flamegraphs-recursive/high.svg&quot; alt=&quot;Tower of flame.&quot; /&gt;
  
  &lt;figcaption&gt;Tower of flame.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;A high tower, isn’t it?
We can see sequences of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odd&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odd&lt;/code&gt;, …,
which represent a snapshot of the call stack.
Unfortunately, if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odd&lt;/code&gt; would call other functions to perform some actual work
(as was the case for my own application),
we could not easily see the cost of these other functions, as
we would not see the forest for the trees.&lt;/p&gt;

&lt;p&gt;The solution is the following: Scrap &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cargo flamegraph&lt;/code&gt;.
We will manually fiddle with the perf output.&lt;/p&gt;

&lt;p&gt;For this, I created a script that I called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;graph.sh&lt;/code&gt;.
It runs a given command and collapses recursive calls to a single call.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# name of the cargo package (substitute &apos;-&apos; with &apos;_&apos;!)&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;even_odd

&lt;span class=&quot;c&quot;&gt;# run the command given in the arguments and collect performance statistics&lt;/span&gt;
perf record &lt;span class=&quot;nt&quot;&gt;--call-graph&lt;/span&gt; dwarf &lt;span class=&quot;nv&quot;&gt;$@&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# process the performance statistics:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# map the first occurrence of either `even` or `odd` in a flame to `eveod`, and drop the rest&lt;/span&gt;
perf script | inferno-collapse-perf | &lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;s/;&apos;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NAME&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;::\(even\|odd\)/;&apos;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NAME&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;::eveod/&apos;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;s/;&apos;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NAME&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;::\(even\|odd\)//g&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; stacks.folded

&lt;span class=&quot;c&quot;&gt;# create the flamegraph&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;stacks.folded | inferno-flamegraph &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; flamegraph.svg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The magic is in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sed&lt;/code&gt; command.
To understand this, just run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;perf script | inferno-collapse-perf&lt;/code&gt; yourself.
This gives you a list of “snapshots”, where every snapshot is a call trace.
In every call trace, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sed&lt;/code&gt;
keeps the first occurrence of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odd&lt;/code&gt;, mapping it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eveod&lt;/code&gt;, and
removes all remaining occurrences of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odd&lt;/code&gt;.
(The replacement name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eveod&lt;/code&gt; must not be a prefix of neither &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even&lt;/code&gt; nor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odd&lt;/code&gt;,
otherwise it is erased by the second &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sed&lt;/code&gt; expression.)&lt;/p&gt;

&lt;p&gt;To use this script:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cargo build
./graph.sh target/debug/even-odd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Its output looks like this:&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2022-04-15-flamegraphs-recursive/flat.svg&quot; alt=&quot;A much nicer flamegraph.&quot; /&gt;
  
  &lt;figcaption&gt;A much nicer flamegraph.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;We can now see that all calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odd&lt;/code&gt; are represented by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eveod&lt;/code&gt;.
If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;even&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;odd&lt;/code&gt; would be calling other functions,
we could now better estimate their costs.&lt;/p&gt;
</description>
        <pubDate>Fri, 15 Apr 2022 00:00:00 +0000</pubDate>
        <link>http://gedenkt.at/blog/flamegraphs-recursive/</link>
        <guid isPermaLink="true">http://gedenkt.at/blog/flamegraphs-recursive/</guid>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Musea</title>
        <description>&lt;p&gt;Seit zwei Wochen sind die Museen in den Niederlanden wieder geöffnet!
Als stolzer Besitzer einer Museumkaart, die mir ein Jahr lang
freien Eintritt zu allen niederländischen Museen ermöglicht hätte
(warum gibt’s sowas eigentlich nicht in Österreich?),
wollte ich es mir darum nicht entgehen lassen,
meinen letzten Monat in den Niederlanden kulturell voll auszukosten.
Und so war ich in den letzten zwei Wochen in folgenden Museen:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://de.wikipedia.org/wiki/Portugiesische_Synagoge_Amsterdams&quot;&gt;Portugees-Israëlietische Synagoge&lt;/a&gt;:
Diese zum Zeitpunkt der Konstruktion älteste Synagoge der Welt
hat mich persönlich eher enttäuscht, da sie im Inneren wie im Äußeren
recht karg und minimalistisch gestaltet ist.
Besonders hat mich überrascht, dass die Synagoge sehr schwach besucht war.
Ich war die meiste Zeit vollkommen alleine in ihrem Inneren.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://de.wikipedia.org/wiki/Micropia&quot;&gt;Micropia&lt;/a&gt;:
Ganz in der Nähe der Synagoge liegt das laut eigenen Angaben
“einzige Mikroben-Museum der Welt”.
In direkter Nachbarschaft zum Zoo “ARTIS” bietet dieses Museum
eine sehr moderne und interaktive Ausstellung.
Man kann z.B. selbst mit dem Mikroskop Bakterien beobachten,
und man kann sehen, wie eine Melone nach mehreren Jahren aussieht
(Antwort: besser, als man denkt!).
Die Botschaft, die bei mir ankommt, ist, dass wir auf unserem Planeten
von deutlich mehr Organismen umgeben sind, als uns das täglich bewusst ist.
Ein absoluter Tipp.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://de.wikipedia.org/wiki/Museum_Het_Rembrandthuis&quot;&gt;Het Rembrandthuis&lt;/a&gt;:
Dieses Museum ist im ehemaligen Wohnhaus von Rembrandt untergebracht,
der sehr feudal im Zentrum von Amsterdam auf mehreren Stockwerken seine Bilder malte
und sich nicht zu schade war, diese bei einem Gläschen Wein selbst zu verkaufen.
Da die Bilder des Rembrandthaus allerdings ohne geschriebene Erklärung auskommen
(oft steht nicht einmal der Künstler oder Titel dabei),
lernt man relativ wenig in der Ausstellung über die Bilder,
jedoch einiges über die Lebensformen der damaligen Zeit.
Interessant z.B. zu sehen, dass die Magd in einem Kastenbett in der Küche schlief.
Dieses Museum ist eher für eingefleischte Rembrandt-Fans zu empfehlen,
die schon über Hintergrundwissen über Rembrandt verfügen.
Dieses bekommt man z.B. im Rijksmuseum (siehe unten).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://de.wikipedia.org/wiki/Rijksmuseum_Amsterdam&quot;&gt;Rijksmuseum&lt;/a&gt;:
Der Klassiker unter den Amsterdamer Museen.
Man sollte hier nicht (wie ich) der Verlockung erliegen,
ein ganzes Stockwerk auf einmal besichtigen zu wollen,
denn aufgrund seiner schieren Größe ist dies nur mit sehr viel Zeit
oder einem sehr oberflächlichen Blick auf die Kunstwerke zu schaffen.
Dieses Museum bietet einen genuin niederländischen Blick auf die Kunstgeschichte
und bietet auch sehr viel Hintergrundinformationen über
die niederländische Geschichte und Kultur.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://de.wikipedia.org/wiki/Tropenmuseum&quot;&gt;Tropenmuseum&lt;/a&gt;:
Die Niederlande haben eine lange koloniale Geschichte,
die bis ins 16. Jahrhundert zurückreicht.
Das Tropenmuseum (vormals Kolonialmuseum) zeigt
die Kultur der kolonialisierten Länder
(insbesondere Indonesien und Papua) sowie deren
Reaktion auf die Kolonialisierung und Freiheitskampf.
Mich hat hier insbesondere die sehr archaische Kultur Papuas fasziniert,
sowie die niederländische Schleifung der alten Königsstadt Jakarta und
der Aufbau einer neuen Stadt Batavia an gleicher Stelle nach Amsterdamer Vorbild.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://de.wikipedia.org/wiki/Verzetsmuseum_Amsterdam&quot;&gt;Verzetsmuseum&lt;/a&gt;:
Das Widerstandsmuseum zeichnet
die Geschichte der Niederlande im zweiten Weltkrieg nach.
Noch unter dem Eindruck des Tropenmuseums habe ich mich hier
auf die Ausstellung über den Widerstand in Indonesien gegen
die japanische Besetzung konzentriert, die äußerst brutal vorgegangen ist.
Widerstand wurde von dieser meistens so beantwortet: Kopf ab!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://de.wikipedia.org/wiki/Van_Gogh_Museum&quot;&gt;Van Gogh Museum&lt;/a&gt; (x2):
Dieses Museum erläutert den Werdegang van Goghs,
der seine ersten Lehrjahre in den Niederlanden durchmachte,
jedoch erst in Frankreich zu seiner eigentlichen künstlerischen Blüte gelangte.
Dieses Museum gefiel mir so gut, dass ich es gleich zweimal besuchte.
Es zeigt sehr viele absolute Klassiker van Goghs
(wie die “Sonnenblumen” und das “Schlafzimmer”),
bietet aber auch sehr viele Hintergrundinformationen zu diesem
sehr kultivierten Ausnahmekünstler.
Ebenfalls eine absolute Empfehlung!&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-06-20-musea/IMG_20210612_134513.jpg&quot; alt=&quot;Tropenmuseum.&quot; /&gt;
  
  &lt;figcaption&gt;Tropenmuseum.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Ein Besuch in den Museen gestaltet sich momentan als etwas mühsam,
da man sich immer vorab im Internet einen “tijdslot” (Zeitschlitz) reservieren muss.
Doch ab dem 26. Juni sollen diese und andere Corona-Maßnahmen weiter gelockert werden
und sogar die Maskenpflicht (mit Ausnahme des öffentlichen Verkehrs) fallen.
Das finde ich gelinde gesagt gewagt.
Unsere Nachbarn unter uns sitzen gerade mit Corona in Quarantäne,
was exemplarisch zeigt, dass die Pandemie noch nicht vorbei ist.
Allerdings waren die Niederländer noch nie sehr diszipliniert
im Umgang mit Masken, weshalb dieser Schritt der Regierung vielleicht
eh keine sehr große Änderung darstellt.&lt;/p&gt;

&lt;p&gt;Doch momentan ist ein Thema deutlich wichtiger als Corona für die Niederländer:
Fußball!
Amsterdam war ja Austragungsort einiger Spiele,
insbesondere auch des Spiels gegen Österreich.
Kurz vor dem Spiel habe ich durch Zufall beim Zoo “ARTIS”
den Teambus der österreichischen Mannschaft gesichtet.
Leider kam mir erst zu spät der Gedanke,
eine kleine aufmunternde Botschaft an den Bus zu heften.&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-06-20-musea/IMG_20210615_170524.jpg&quot; alt=&quot;Tropenmuseum.&quot; /&gt;
  
  &lt;figcaption&gt;Tropenmuseum.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Insofern trage ich ein bisschen Verantwortung für die österreichische Niederlage,
die ich akustisch mitverfolgen konnte, da wir während unseres Abendessens
immer wieder Jubelgeschrei von der Straße hören konnten.
Ich gestehe, dass dies — obwohl ich nicht fußballinteressiert bin —
eher schmerzhaft für mich war.
Am Tag darauf wurde ich sogar im Van Gogh Museum auf das Spiel angesprochen,
nachdem ich mich als Österreicher zu erkennen gegeben hatte.
Die Niederländer waren allerdings immer sehr respektvoll mit mir,
keine Spur von Häme oder Überlegenheit.&lt;/p&gt;

&lt;p&gt;Ich muss sagen, dass ich mich in den letzten Wochen
weitgehend mit den Niederlanden ausgesöhnt habe.
Hegte ich zuvor schon sehr negative Gefühle gegen dieses Land,
zeigte es sich nun von seinen besseren Seiten.
Das mag nicht unwesentlich mit dem sehr guten Wetter zu tun haben,
aber auch mit der Abwesenheit unserer Nachbarin,
weshalb ich mich jetzt auch in unserer Wohnung deutlich besser fühle.
Vielleicht spielt aber auch eine Rolle,
dass unsere Tage hier gezählt sind, weshalb sie wertvoller erscheinen.
Allerdings: Man sollte dann gehen, wenn’s am schönsten ist.&lt;/p&gt;

&lt;p&gt;Die Vorbereitungen für unseren Umzug sind jedenfalls voll im Gange:
Der Makler, der uns die Wohnung ursprünglich gezeigt hatte,
organisierte zwei Wohnungsbesichtigungen,
wobei sich bei der zweiten Besichtigung ein Nachmieter ab dem 1. Juli fand.
Somit müssen wir voraussichtlich keine Miete doppelt zahlen,
was besonders bei den Amsterdamer Mietpreisen sehr angenehm ist.
(Kleines Detail am Rande:
Einer meiner Studenten, der aus Amsterdam stammt, erzählte mir,
dass es eine Warteliste von etwa zwanzig Jahren (!) auf Gemeindewohnungen
in Amsterdam gibt. Sein Kommentar: “Housing in Amsterdam is a shitshow.”)&lt;/p&gt;

&lt;p&gt;Auch der Transport unserer Siebensachen nach Innsbruck
ist jetzt weitgehend geregelt — die Spedition &lt;a href=&quot;https://www.kattenberg.nl/&quot;&gt;Kattenberg&lt;/a&gt; erledigt dies
von Wohnung zu Wohnung für 950€.
Die Spedition transportiert fast alle unsere Sachen,
nur für einen Kasten müssen wir noch einen Käufer finden.&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-06-20-musea/IMG_20210615_140129.jpg&quot; alt=&quot;Transportsimulation.&quot; /&gt;
  
  &lt;figcaption&gt;Transportsimulation.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Für meine Rückfahrt nach Tirol habe ich jetzt auch schon einen Zugfahrschein:
Ich komme am 30. Juni planmäßig um 19:18 in Innsbruck Hauptbahnhof an.
Dies bedeutet leider auch, dass ich meinen Gedanken,
mit dem Fahrrad nach Tirol zu fahren, begraben muss.
Diesen Gedanken habe ich immer im Hinterkopf behalten,
aber wegen Corona, Übersiedlung und Betreuung von Studenten
(die Anfang bis Mitte Juli ihre Arbeiten abgeben und ihre Präsentationen halten werden)
ist dies leider nicht der richtige Zeitpunkt für eine solche Unternehmung.&lt;/p&gt;

&lt;p&gt;Ich lerne jedenfalls noch soviel Niederländisch wie möglich,
auch durch die Museumsbesuche, bei denen ich mittlerweile
zu 90% die niederländischen Texte lese.
Auch wickle ich jegliche schriftliche Korrespondenz auf Niederländisch ab;
am Telefon bin ich allerdings noch nicht sattelfest genug.
Die Niederländer goutieren diese Anstrengungen durchaus
und zeigen sich sehr erfreut über meine Anstrengungen.&lt;/p&gt;

&lt;p&gt;Mathilde hat am letzten Wochenende ihre Arbeit beendet,
worüber sie sehr glücklich ist, insbesondere auch deshalb,
weil sie jetzt nicht mehr am Wochenende arbeiten muss.
So konnten wir diesen Samstag zu zweit eine Tour nach Haarlem machen,
gefolgt von einer Tour durch die Dünen.
Wir machten einen Zwischenstopp bei dem Dünensee “‘t Wed”, wo wir uns an
einem Streit zwischen einer heimtückischen Möwe und einer Familie ergötzten.
Danach ging es über Santpoort und Spaarndam zurück nach Amsterdam.&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-06-20-musea/IMG_20210619_174454.jpg&quot; alt=&quot;&apos;t Wed.&quot; /&gt;
  
  &lt;figcaption&gt;&apos;t Wed.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Bis bald!&lt;/p&gt;

</description>
        <pubDate>Sun, 20 Jun 2021 00:00:00 +0000</pubDate>
        <link>http://gedenkt.at/amsterdam/musea/</link>
        <guid isPermaLink="true">http://gedenkt.at/amsterdam/musea/</guid>
        
        
        <category>amsterdam</category>
        
      </item>
    
      <item>
        <title>Amsterdam gaat weer open</title>
        <description>&lt;p&gt;Amsterdam hat sich in den letzten Wochen erstaunlich gewandelt.
Zeigte die Stadt zuvor die meiste Zeit ihr eher winterliches Gesicht,
hat sich Amsterdam — schon allein klimatisch — sommerlich aufgebrezelt.
Und so tauschte ich innerhalb weniger Tage die Handschuhe gegen kurze Hosen ein.
In der Nähe unseres Hauses, an der Erasmusgracht, finden sich nunmehr
täglich Menschen ein, die in der Gracht schwimmen gehen.&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-06-07-amsterdam-gaat-weer-open/IMG_20210602_162306.jpg&quot; alt=&quot;Erasmusgracht.&quot; /&gt;
  
  &lt;figcaption&gt;Erasmusgracht.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Auch ich folgte dem Lockruf des Wassers und fuhr mit Mathilde
in den Amsterdamse Bos, wo ich mich in ein ruhiges Wässerchen begeben wollte.
Doch die Suche nach einem ruhigen Plätzchen stellte sich als schwierig heraus,
da das Nieuwe Meer von partywütigen Bootsfahrern gestürmt wurde,
die gerne ihre basslastigen Lautsprecher aufdrehten.
Endlich an einer lauschigen Lagune am Rande eines Sees
im Inneren des Waldes angekommen,
versuchte ich in das sehr seichte Wasser zu gehen.
Doch stellte sich heraus, dass der vermeintliche Grund des Wasser nur eine
lose Schicht aus Blättern war, unter der sich ca. ein Meter Schlamm verbarg.
In der Hoffnung, dass ich oberhalb dieses Schlamms schwimmen könnte,
stieg ich mit beiden Beinen in den Schlamm und ließ mich dann ins Wasser fallen.
Mein Kalkül ging nicht auf; ich wirbelte eine riesige Menge Schlamm
gemischt mit algenartigen Pflanzen auf, die mich übelriechend umhüllten
und eilends zurück ans Ufer fliehen ließen.&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-06-07-amsterdam-gaat-weer-open/IMG_20210611_181324.jpg&quot; alt=&quot;Die Lagune des Schreckens.&quot; /&gt;
  
  &lt;figcaption&gt;Die Lagune des Schreckens.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Von Algen eingehüllt fuhr ich ein wenig weiter und fand einen kleinen Strand,
wo sich ein paar Dutzend Leute aufhielten und auch schwammen.
Dadurch beruhigt eilte ich in das Wasser, um den ekelhaften Schlamm
loszuwerden, konnte aber selbst nach mehr als einer Viertelstunde Schwimmen
noch die Residuen meines unglücklichen ersten Schwimmversuchs deutlich riechen
und erst nach einer eingehenden Dusche loswerden.
Im Gespräch mit Niederländern fand ich heraus, dass die Wasserqualität
in den Amsterdamer Gewässern eher bescheiden ist,
was ich nach meinen eigenen Erfahrungen deutlich bestätigen kann.
Es ist auch verdächtig, dass trotz immer höherer Temperaturen
nur ein Bruchteil der Leute in das kühle Nass steigt und
der Großteil sich damit begnügt, an den Ufern der Grachten zu brutzeln
(sowohl sich selbst als auch Würsteln &amp;amp; Co.).&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-06-07-amsterdam-gaat-weer-open/IMG_20210604_182111.jpg&quot; alt=&quot;Kleine Vijver.&quot; /&gt;
  
  &lt;figcaption&gt;Kleine Vijver.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Abgesehen von den höheren Temperaturen fühlt sich Amsterdam angenehmer an,
da nunmehr immer mehr Einrichtungen (darunter auch Museen) geöffnet sind.
Am Sonntag war ich z.B. zum ersten Mal in diesem Jahr mit Mathilde
in einem Restaurant, wenngleich “nur” auf einer Terrasse im Freien.
Ein kurzer Blick ins Innere des Restaurants enthüllte,
dass im Inneren die Leute dicht gedrängt beieinander saßen,
und weder Kellner noch Gäste Masken trugen.
Ich fühlte mich mit meiner FFP2-Maske ein bisschen wie
ein Alien in einer vorgeblichen Post-Corona-Welt.
Am Sonntag hatte ich auch Amsterdam bei strahlendem Wetter erkundigt,
und es kam ein bisschen Wehmut in mir auf,
da ich ja doch Amsterdam in dem Moment verlassen werde,
wo es sich gerade anschickt, angenehm zu werden.
Doch gedenke ich, aus der mir noch zustehenden Zeit das meiste herauszuholen,
in dem ich unter anderem noch so viele Museen besichtigen möchte wie möglich.
Viel von meinem momentanen Komfort ist auch der Tatsache geschuldet,
dass unsere Nachbarin so gut wie nie zuhause ist, und wir somit sowohl
ihrer Waschmaschine als auch ihrer Schritte entledigt sind,
was mich schon deutlich entspannter wohnen lässt.
Der Schiller hatte schon irgendwie Recht …&lt;/p&gt;

</description>
        <pubDate>Mon, 07 Jun 2021 00:00:00 +0000</pubDate>
        <link>http://gedenkt.at/amsterdam/amsterdam-gaat-weer-open/</link>
        <guid isPermaLink="true">http://gedenkt.at/amsterdam/amsterdam-gaat-weer-open/</guid>
        
        
        <category>amsterdam</category>
        
      </item>
    
      <item>
        <title>Vakantie</title>
        <description>&lt;p&gt;Nach ein paar wunderschönen Wochen in Tirol bin ich
am 14. Mai wieder nach Amsterdam zurückgekehrt.
Was mir in der Wohnung als erstes auffiel, waren die vielen Kisten,
die an den Eingängen zu Küche, Wohnzimmer und Schlafzimmer standen.
Mathilde hatte mich schon vorgewarnt, dass sie während meiner Abwesenheit
in der Wohnung Bekanntschaft mit (mindestens) einer Maus gemacht hatte,
und erklärte mir, dass sie diese Kisten als Maus-Barrikade eingerichtet hatte.
Bei der Verfolgung der Maus (für die Mathilde ein Stück savoyardischen Käses opferte)
hatte Mathilde festgestellt, dass diese
in einem Wandschrank verschwunden und anschließend nicht mehr aufzufinden war.
In besagtem Wandschrank befindet sich ein Wasserrohr, welches durch ein Loch
in der Wand führt, welches nicht vollständig abgeschlossen war.
Seitdem Mathilde die offenen Stücke des Lochs mit Klebestreifen abgedichtet hatte,
war von dem mäuslichen Besucher nichts mehr zu sehen.&lt;/p&gt;

&lt;p&gt;Am Samstag fuhr ich abends noch eine Runde in den “Amsterdamse Bos”,
mit dem Hintergedanken, danach Mathilde von der Arbeit abzuholen.
Dies war mir möglich, nachdem ja die abendliche Ausgangssperre
in den Niederlanden mittlerweile wieder Geschichte ist.
Bei dem Massagesalon angekommen bot mir Mathilde noch eine kleine Massage an,
womit ich zum ersten Mal ihren Arbeitsplatz sah.
Nach einer Dreiviertelstunde war leider schon Schluss,
denn mein recht verspannter Nacken (Fluch aller Heimarbeiter!)
hätte sich noch mehr gewünscht.
Am Tag darauf wiederholte sich das Prozedere,
nur dass die Massage diesmal ca. eineinhalb Stunden lang ausfiel
und sich mein Nacken diesmal nicht über unzureichende Behandlung beklagen konnte. :)&lt;/p&gt;

&lt;p&gt;In dem Massagesalon ist es üblich, nach der Massage noch einen Tee einzunehmen.
An dem Tisch, wo der Tee steht, lag auch ein Buch über Bruce Springsteen
namens “Springsteen in Nederland”.
Darin erfuhr ich, dass Springsteen ein niederländischer Name ist,
jedoch trotz weitgehender Bemühungen nicht zweifelsfrei nachgewiesen ist,
dass der Sänger niederländische Wurzeln hat
(was für die Niederländer von großer Bedeutung zu sein scheint).
In diesem Buch hat eine Auflistung von englischen Redensarten über Niederländer
meine Aufmerksamkeit erregt. Beispiele gefällig?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“Dutch agreement”: Übereinkunft zwischen zwei Menschen, die zustande kommt,
wenn beide betrunken sind, und an die sich beide später nicht mehr erinnern&lt;/li&gt;
  &lt;li&gt;“Dutch concert”: Lärmbelästigung&lt;/li&gt;
  &lt;li&gt;“Dutch consolation”: schaler Trost&lt;/li&gt;
  &lt;li&gt;“Dutch defense”: schwache Verteidigung&lt;/li&gt;
  &lt;li&gt;“Dutch generosity”: Gier&lt;/li&gt;
  &lt;li&gt;“Dutch humour”: augenzwinkernder/ironischer Humor&lt;/li&gt;
  &lt;li&gt;“Dutch treat”: wenn man auf ein Abendessen eingeladen wird,
wobei man davon ausgeht, dass man nichts dafür bezahlen muss,
am Ende allerdings doch eine Rechnung serviert bekommt&lt;/li&gt;
  &lt;li&gt;“Going Dutch”: wenn man mit Freunden ausgeht und die Rechnung geteilt wird,
sodass jeder sein eigenes Essen und Trinken bezahlt&lt;/li&gt;
  &lt;li&gt;“End up in Dutch”: in Ungnade fallen&lt;/li&gt;
  &lt;li&gt;“Dutch uncle”: Person, die man lieber vermeidet, da diese einem
herablassend oder ermahnend zuredet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alles in allem scheinen also Niederländer bei Engländern &amp;amp; Co.
nicht gerade positiv konnotiert zu sein.
Interessanterweise fallen mir im Deutschen kaum
vergleichbare Redensarten über Niederländer ein,
was man als Beleg dafür deuten könnte, dass die Niederlande
stärker Richtung England/Amerika als Richtung Europa orientiert sind.
(Außer vielleicht für die Ferien.)&lt;/p&gt;

&lt;p&gt;Auch viele Niederländer scheinen eine geradezu masochistische Tendenz zu haben,
schlechtes über ihr eigenen Land hören zu wollen oder zu sagen.
So hat zum Beispiel Mathilde einen Klienten gehabt, der sie am Ende der Massage gefragt hat:
“So, what do you really think about the Netherlands? I like to hear bad stuff!”
Und weiters gibt es ein Video von &lt;a href=&quot;https://www.learndutch.org/dutch-culture/what-is-typical-dutch-food-foreigners-talk-about-dutch-food/&quot;&gt;Bart de Pau&lt;/a&gt; ein,
in dem er fast genüsslich über
die schlimmsten kulinarischsten Sünden der Niederländer referiert.
Gleichzeitig sind Niederländer aber auch sehr patriotisch (Oranje!),
was für mich eine sehr unverständliche Mischung darstellt.&lt;/p&gt;

&lt;p&gt;Ein schönes Beispiel für einen “Dutch oncle” fällt mir jedenfalls aus dem Stegreif ein:
Hugo de Jonge, seines Zeichens niederländischer Gesundheitsminister.
Dieser hat sich in die Nesseln gesetzt, als er &lt;a href=&quot;https://www.nrc.nl/nieuws/2021/05/12/gewoon-thuis-een-mooie-dvd-opzetten-a4043369&quot;&gt;folgendes verkündete&lt;/a&gt;:
“Je hoeft niet naar het theater. Je kunt ook thuis een mooie dvd opzetten.”
(“Du musst nicht ins Theater. Du kannst auch zuhause eine hübsche DVD auflegen.”)
Der Hintergrund dieser flapsigen Aussage ist, dass die Niederlande beschlossen haben,
mit dem nächsten Öffnungsschritt per 19. Mai etliche Einrichtungen wie etwa
Fitnessstudios und Bordelle (!) zu öffnen, jedoch
Museen, Theater und Kinos geschlossen zu halten.
Dies hat Kulturschaffende erzürnt und zu Kommentaren verleitet wie:
“Ins Theater zu gehen ist wie Liebe machen mit drei Kondomen übereinander.
Es geht kaum sicherer.”&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.nrc.nl/nieuws/2021/05/13/hugo-de-jonges-opmerking-over-een-dvdtje-is-een-sneer-naar-de-kunst-a4043477&quot;&gt;Ein sehr interessanter Artikel&lt;/a&gt;
führt die Geringschätzung der Kultur in den Niederlanden darauf zurück,
dass die Niederlande — anders als der Rest Europas — keine höfische,
sondern eine bürgerliche Kultur hatten, weshalb dort ein Krämergeist vorherrsche.
Der Artikel weiters:
“Aus einer neoliberalen Sicht dient alles der Wirtschaft, und
Kultur wird als ein Instrument dafür gesehen.
Wenn man an alles das Kriterium des Nutzens anlegt, ist Kunst nicht wichtig.”
Für mich wird immer sichtbarer, dass der in den Niederlanden vorzufindende Krämergeist
ein Wegbegleiter des Neoliberalismus ist, dessen ideologische Wurzeln gleichfalls
in den liberalen, bürgerlichen Niederlanden zu verorten sind.&lt;/p&gt;

&lt;p&gt;Ich halte es in dem Kontext für höchst relevant, dass New York ursprünglich
eine niederländische Niederlassung, nämlich &lt;a href=&quot;https://de.wikipedia.org/wiki/Nieuw_Amsterdam&quot;&gt;Nieuw Amsterdam&lt;/a&gt;, war.
Ich mutmaße, dass sich die niederländischen Werte dadurch
Geltung in den heutigen USA verschafft und erhalten haben,
von wo sie sich als Leitkultur die ganze Welt zu erobern anschicken.
Nannte doch nicht umsonst ein österreichischer Einwanderer in den USA die Amerikaner
“himmelanstinkende Krämerseelen. Tot für alles geistige Leben, maustot.”
(Quelle: &lt;a href=&quot;https://www.welt.de/politik/wahl/us-wahl-2012/article110671756/America-the-Great-Was-Groesse-wirklich-ausmacht.html&quot;&gt;WELT&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Eine weitere Folge der liberalen Corona-Politik der Niederlande ist übrigens,
dass aufgrund hoher Fallzahlen (vor kurzem ca. vier Mal so hoch wie in Österreich!)
noch bis voraussichtlich 30. Juni in Österreich eine Quarantänepflicht
bei einer Einreise aus den Niederlanden gilt.
Dies könnte unseren Umzug nach Tirol etwas erschweren.&lt;/p&gt;

&lt;p&gt;Bezüglich des Umzugs:
Ich habe in der letzten Woche vor meiner Abfahrt aus Tirol noch
zwei Wohnungen besichtigt und kurz nach meiner Rückkehr nach Amsterdam
den Zuschlag für eine Wohnung in St. Nikolaus erhalten!
So scheint es nunmehr immer wahrscheinlicher,
dass ich nach meiner Rückkehr nach Tirol ein “Koatlackler” werde.&lt;/p&gt;

&lt;p&gt;Und wenn wir schon beim Thema Rückkehr sind:
Diese könnte eventuell mit folgendem Verkehrsmittel stattfinden,
von dem das erste Exemplar heute gestartet ist:&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-05-24-vakantie/IMG_20210523_195945.jpg&quot; alt=&quot;Dat is toch top!&quot; /&gt;
  
  &lt;figcaption&gt;Dat is toch top!&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Die erste Österreich-Werbung, die ich seit meiner Ankunft in Amsterdam gesehen habe!
Dieses Wochenende waren übrigens unüblich viele Autos mit ausländischem Kennzeichen
auf den Straßen von Amsterdam, darunter sehr viele Franzosen,
von denen wohl einige zum ersten Mal seit langem wieder einmal aus ihrem Land herauskommen.
Kombiniert mit den geöffneten Terrassen vor den Restaurants
fühlt sich Amsterdam langsam wieder normal an …&lt;/p&gt;

&lt;p&gt;Ich wünsche meiner Leserschaft eine schöne Woche und bis bald!&lt;/p&gt;

</description>
        <pubDate>Mon, 24 May 2021 00:00:00 +0000</pubDate>
        <link>http://gedenkt.at/amsterdam/vakantie/</link>
        <guid isPermaLink="true">http://gedenkt.at/amsterdam/vakantie/</guid>
        
        
        <category>amsterdam</category>
        
      </item>
    
      <item>
        <title>Zee en Meer</title>
        <description>&lt;p&gt;In der Woche vom 12. April begann gefühlt der Sommer in Amsterdam.
Die Menschen rauchten ein gemütliches Jointerl oder tranken ein Glaserl Wein
vor ihren Häuser, und die Parks füllten sich erneut mit Leben.
Eine ganz neue Atmosphäre machte sich breit.&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-04-26-zee-en-meer/IMG_20210413_180942.jpg&quot; alt=&quot;Zomer in Amsterdam.&quot; /&gt;
  
  &lt;figcaption&gt;Zomer in Amsterdam.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Ich nutzte das schöne Wetter, um einen zweiten Anlauf Richtung Meer zu wagen.
Diesmal sollte es mir gelingen, die psychologische Haarlemer Schranke zu überwinden.
Ursprünglich wollte ich bei &lt;a href=&quot;https://de.wikipedia.org/wiki/Zandvoort&quot;&gt;Zandvoort aan Zee&lt;/a&gt; das Meer erreichen.
Doch schon einige Kilometer nach Haarlem hörte ich von einer Aussichtsplattform aus
laute Motorengeräusche (die bei weiterer Annäherung immer stärker wurden) aus Richtung Zandvoort,
und auch die Hochhauskulisse Zandvoorts verzauberte mich enden wollend.
So entschloss ich mich dazu, Zandvoort zu umfahren und erst bei Bloemendaal das Meer zu erreichen.
Bei dem Weg dorthin kam ich direkt an der Lärmquelle vorbei, nämlich dem &lt;a href=&quot;https://de.wikipedia.org/wiki/Circuit_Park_Zandvoort&quot;&gt;Circuit Park Zandvoort&lt;/a&gt;,
wo übrigens Niki Lauda das bisher letzte Rennen gewonnen hatte.
Nach der Rennstrecke ging es durch eine sehr
kurvige, windige und etwas eintönige Dünenlandschaft nach Bloemendaal.
Dort angekommen allerdings weder eine Spur vom Meer noch von Blumen,
jedoch eine mäßig einladende Betonwüste.
So fuhr ich noch ein Stück weiter zu einem Ort namens Parnassia aan Zee,
wo ich endlich das Meer erblickte (und mir einen Kaffee gönnte).&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-04-26-zee-en-meer/IMG_20210416_162025.jpg&quot; alt=&quot;Heimlicher Star: die Möwe.&quot; /&gt;
  
  &lt;figcaption&gt;Heimlicher Star: die Möwe.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-04-26-zee-en-meer/IMG_20210416_164344.jpg&quot; alt=&quot;Kitesurfer und Hochhäuser.&quot; /&gt;
  
  &lt;figcaption&gt;Kitesurfer und Hochhäuser.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Das Wasser machte leider keinen sehr einladenden Eindruck, und ein paar Damen,
die nach wenigen Sekunden Wasserkontakt schnell wieder umdrehten, bestätigten dies.
Die zahlreichen Kitesurfer ließen sich davon jedoch nicht abschrecken.&lt;/p&gt;

&lt;p&gt;An dieser Stelle ein wenig Linguistik:
Der Niederländer nennt das Meer “Zee”, und den See (wie auch das deutsche “mehr”) “Meer”.
Der Titel dieses Artikels ist somit mehrdeutig:
Entweder “Meer und mehr”, oder “Meer und See”. :)&lt;/p&gt;

&lt;p&gt;Zurück Richtung Haarlem ging es durch eine pittoreske, wenn auch etwas triste Dünenlandschaft.&lt;/p&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-04-26-zee-en-meer/IMG_20210416_165716.jpg&quot; alt=&quot;&quot; /&gt;
  
  &lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure class=&quot;image&quot;&gt;
  
  &lt;img src=&quot;/media/2021-04-26-zee-en-meer/IMG_20210416_171050.jpg&quot; alt=&quot;Man beachte die windbedingte Neigung der Bäume.&quot; /&gt;
  
  &lt;figcaption&gt;Man beachte die windbedingte Neigung der Bäume.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure class=&quot;image&quot;&gt;
&lt;div id=&quot;map&quot; style=&quot;height: 600px;&quot;&gt;&lt;/div&gt;
&lt;figcaption&gt;Amsterdam -- Haarlem -- Zandvoort -- Santpoort -- Spaarndam -- Amsterdam.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;script&gt;
var newMap = L.map(&apos;map&apos;);
L.tileLayer(&apos;http://{s}.tile.osm.org/{z}/{x}/{y}.png&apos;, {
  attribution: &apos;&amp;copy; &lt;a href=&quot;https://www.openstreetmap.org/copyright&quot;&gt;OpenStreetMap&lt;/a&gt; contributors&apos;
}).addTo(newMap);
fetch(&apos;/media/2021-04-26-zee-en-meer/zee.geojson&apos;)
  .then(response =&gt; response.json())
  .then(data =&gt; newMap.fitBounds(L.geoJson(data).addTo(newMap).getBounds()));
&lt;/script&gt;

&lt;p&gt;Am Dienstag, den 20. April, fuhr ich wie geplant mit dem Zug nach Österreich.
Dabei kam ich auch durch Utrecht, welches ich im letzten Artikel als potenzielle
Wohnort-Alternative zu Amsterdam ins Spiel gebracht hatte.
Doch fand ich die Hochhauskulisse um den Bahnhof herum so hässlich,
dass ich diesen Plan eilends wieder verwarf.
In Richtung der deutschen Grenze wies mich dann ein Schaffner darauf hin,
dass ich für die Durchreise durch Deutschland einen PCR-Test benötige,
sofern ich nicht ohne Umstieg mit dem Zug weiter zu seinem Endbahnhof Basel führe.
Mein Hinweis auf die geltenden Richtlinien, die nichts von Umstiegen erwähnen,
quittierte er mit dem Hinweis, dass ich dann eben 500€ in Deutschland zahlen müsse,
sollte ich kontrolliert werden, und legte mir nahe, in Arnhem auszusteigen und einen Test nachzuholen.
Nachdem ich mich jedoch im Recht wähnte, blieb ich im Zug sitzen,
nicht ohne aber an der Grenze etwas ins Schwitzen zu geraten.
Doch an der Grenze und auch danach fand keine Kontrolle statt,
sodass ich glücklicherweise nicht mit deutschen Polizisten streiten musste.
Nach diesem Zwischenfall ging alles wie am Schnürchen,
und ohne eine einzige Minute Verspätung erreichte ich planmäßig die Karwendelbahn in München.
In Scharnitz war ebenfalls keine Kontrolle,
jedoch überraschte mich mein Cousin im Zug, sodass wir zu zweit
die wunderbare Abfahrt zwischen Seefeld und Innsbruck bei Sonnenuntergang genießen konnten.&lt;/p&gt;

&lt;p&gt;Am Mittwoch ließ ich mich beim Olympiastadion testen.
Ich war von der Geschwindigkeit und dem reibungslosen Ablauf sehr beeindruckt.
Danach ging ich wie vorgesehen in Quarantäne, die ich
für meine Arbeit glücklicherweise produktiv nutzen konnte.
Am Sonntag ließ ich mich dann zum zweiten Mal testen,
und machte dann nach Erhalt meines negativen Ergebnisses (per SMS)
eine Rodeltour in &lt;a href=&quot;http://www.winterrodeln.org/wiki/Praxmar&quot;&gt;Praxmar&lt;/a&gt;, um doch noch ein bisschen Wintergefühl genießen zu können.&lt;/p&gt;

</description>
        <pubDate>Mon, 26 Apr 2021 00:00:00 +0000</pubDate>
        <link>http://gedenkt.at/amsterdam/zee-en-meer/</link>
        <guid isPermaLink="true">http://gedenkt.at/amsterdam/zee-en-meer/</guid>
        
        
        <category>amsterdam</category>
        
      </item>
    
      <item>
        <title>Besluit</title>
        <description>&lt;p&gt;Die letzten zwei Wochen haben es in sich gehabt.&lt;/p&gt;

&lt;p&gt;Die Woche des 29. März begann mit ca. 18°C und steigerte sich auf 22°C am Mittwoch.
Schon bei diesen Temperaturen heizte sich unser Wohnzimmer unangenehm auf,
was mir klar vor Augen führte, dass der Ventilator in unserem Wohnzimmer
keineswegs nur zur Dekoration dient, sondern im Sommer unabdingbar ist.
Auch wenn am Tag darauf die Temperatur wieder auf maximal 14°C fiel, war meine Sorge gesät.&lt;/p&gt;

&lt;p&gt;Am Freitag, den 2. April, hatte ich einen richtig unangenehmen Tag:
Nicht nur flogen wieder unentwegt Flugzeuge über unsere Wohnung hinweg,
sondern unsere Nachbarin machte wieder jede Menge Krach.
Sie lässt nämlich fast jeden Tag ihre Waschmaschine laufen,
was man durch äußerst starke Vibrationen in unserer ganzen Wohnung spürt
und unsere Teller fröhlich tanzen lässt.
Weiters hatte es draußen nur mehr ca. 8°C,
ich hatte schlecht geschlafen,
konnte aufgrund eines technischen Defekts niemanden anrufen, und
erwartete Mathilde erst gegen 22 Uhr zurück in der Wohnung.
Dies trieb mich in meiner zunehmenden Verzweiflung auf die Seite der Deutschen Bahn,
um mich über eine baldige Flucht in Richtung Heimat zu informieren.
Trotz des sehr günstigen Fahrpreises von 39,90€ bis Innsbruck
zögerte ich, meinen Kauf zu bestätigen,
da ich ja bei einer Fahrt nach Österreich mindestens fünf Tage in Quarantäne muss.
In dem Moment hörte ich in der Wohnung oberhalb einen lauten Knall
(es wird wohl etwas auf den Boden gefallen sein),
was meine letzten Zweifel ausräumte, und ich klickte auf “Kaufen”.
Somit komme ich — so Gott will — am 20. April um 19:10 in Innsbruck Allerheiligenhöfe an,
nach einer Fahrt über die wunderschöne Strecke der &lt;a href=&quot;https://de.wikipedia.org/wiki/Mittenwaldbahn&quot;&gt;Karwendelbahn&lt;/a&gt;.
Doch Gott hat zwischen die Niederlande und Österreich noch ein Land gesetzt,
welches sich ja schon bei vergangenen Zugreisen als Hemmschuh erwiesen hat.
Da ich &lt;a href=&quot;https://tirol.orf.at/stories/3093416/&quot;&gt;das Schicksal unseres Landeshauptmanns&lt;/a&gt;
ungern teilen möchte, habe ich mich bezüglich der rechtlichen Bestimmungen
bei der Durchreise durch Deutschland informiert.
Der &lt;a href=&quot;https://www.auswaertiges-amt.de/de/quarantaene-einreise/2371468&quot;&gt;relevante Passus&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Transitreisende&lt;/strong&gt; (außer bei Flugreisen) aus
Hochinzidenzgebieten und sonstigen Risikogebieten
sind unter bestimmten Umständen &lt;strong&gt;von der Testpflicht ausgenommen&lt;/strong&gt;.
Hierzu gehört
der Transit ohne Zwischenaufenthalt durch
ein Risikogebiet vor Einreise nach Deutschland wie auch
der &lt;strong&gt;Transit durch Deutschland auf schnellstem Weg&lt;/strong&gt;.
Für die Einreise aus &lt;strong&gt;Virusvariantengebiet&lt;/strong&gt; bestehen grundsätzlich
keine Ausnahmen für den Nachweis eines negativen Testergebnisses bei Einreise.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sind die Niederlande ein sogenanntes Virusvariantengebiet, wie es Tirol war?
Laut dem &lt;a href=&quot;https://www.rki.de/DE/Content/InfAZ/N/Neuartiges_Coronavirus/Risikogebiete_neu.html&quot;&gt;Robert-Koch-Institut&lt;/a&gt;
derzeit nicht, doch ich werde diese Seite im Auge behalten.&lt;/p&gt;

&lt;p&gt;Weiters:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Die Pflicht zur häuslichen Absonderung besteht nicht bei Transitaufenthalten.
Sie sind in diesem Falle allerdings verpflichtet, Deutschland unmittelbar zu verlassen.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Als hätte ich je etwas anderes vorgehabt.&lt;/p&gt;

&lt;p&gt;Und was ist mit der Einreiseanmeldung in Deutschland?
Die Seite ist hier nicht eindeutig, doch
&lt;a href=&quot;https://www.einreiseanmeldung.de&quot;&gt;an anderer Stelle&lt;/a&gt; ist es klarer:
Unter dem Punkt “Wann muss ich meine Daten nicht angeben?” steht unter anderem:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;wenn Sie nur zur Durchreise in die Bundesrepublik Deutschland einreisen und
die Bundesrepublik Deutschland auf schnellstem Wege wieder verlassen,
um die Durchreise abzuschließen, […]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Das bedeutet, dass ich bei der Durchreise durch Deutschland weder
ein Testergebnis mitführen,
in Quarantäne gehen, noch
eine Einreiseanmeldung ausfüllen muss.&lt;/p&gt;

&lt;p&gt;Und wie schaut’s in Österreich aus?
Laut &lt;a href=&quot;https://www.oesterreich.gv.at/themen/coronavirus_in_oesterreich/pre-travel-clearance.html&quot;&gt;dieser Seite&lt;/a&gt; muss ich eine Einreiseerklärung ausfüllen,
mit der ich mich dazu verpflichte, für mindestens fünf Tage in Quarantäne zu gehen.
Ein Testergebnis brauche ich bei der Einreise nicht zwingend,
muss dann aber einen Test bis spätestens 24 Stunden nach meiner Einreise nachholen.&lt;/p&gt;

&lt;p&gt;Und warum lasse ich mich nicht schon vor der Abreise in den Niederlanden testen?
Ich zitiere die Antwort
&lt;a href=&quot;https://www.rivm.nl/en/novel-coronavirus-covid-19/in-depth-information&quot;&gt;der offiziellen Seite des niederländischen Gesundheitsministerium&lt;/a&gt;
auf die Frage “Can I get tested for COVID-19 without symptoms?”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Without symptoms there is no point in getting tested for COVID-19.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ah, welch erfrischend klare Antwort.&lt;/p&gt;

&lt;p&gt;(Ich hätte mich gerne in den Niederlanden vor der Abreise testen lassen,
aber wenn ich dafür einen privates Testlabor bezahlen muss &lt;em&gt;und&lt;/em&gt;
ohnehin kurz nach meiner Ankunft in Österreich testen gehen kann,
dann bevorzuge ich den Test in Österreich.)&lt;/p&gt;

&lt;p&gt;So, genug der Corona-Formalitäten.&lt;/p&gt;

&lt;p&gt;Im Laufe der folgenden Tage ergab sich sowohl bei Mathilde als auch bei mir
immer mehr der Eindruck, dass wir keinen Sinn mehr
in der Fortsetzung unseres Aufenthalts in den Niederlanden sehen.&lt;/p&gt;

&lt;p&gt;Für mich wäre eine Fortsetzung nur
im Falle eines weiteren Wohnungswechsels in Frage gekommen,
da ich in unserer aktuellen Wohnung besonders unter der schlechten Isolation
(sowohl akustisch als auch thermisch) leide.
Wohin jedoch ziehen?
&lt;a href=&quot;https://www.schiphol.nl/en/schiphol-as-a-neighbour/page/is-my-house-underneath-a-flight-path/&quot;&gt;Die Seite des Flughafens Schiphol&lt;/a&gt;
zeigt, dass quasi das gesamte Amsterdamer Stadtgebiet und ein Großteil des Umlands
von Flugzeugen überflogen wird.
Da sich keine andere von uns besichtigte Wohnungen in Amsterdam
durch eine bessere Isolation als die aktuelle ausgezeichnet hat,
ist für mich dadurch der Reiz dieser Stadt ver-flogen.
Man kann dem Flugzeuglärm fast nur dadurch entkommen,
dass man weit entfernt von Amsterdam (und Schiphol) wohnt.
Hierfür wäre für mich maximal ein Ort wie &lt;a href=&quot;https://de.wikipedia.org/wiki/Utrecht&quot;&gt;Utrecht&lt;/a&gt; in Frage gekommen,
wo die Mieten nur ca. halb so teuer sind wie in Amsterdam (!) und
Amsterdam-Zuid mit dem Zug in wenig mehr als 20 Minuten erreichbar ist
(das entspricht in etwa meiner momentanen Reisedauer mit dem Fahrrad zur Universität).
Andererseits wäre das dann schon unser dritter Umzug innerhalb eines halben Jahres,
der dann in spätestens eineinhalb Jahren schon wieder vom nächsten Umzug gefolgt wäre.&lt;/p&gt;

&lt;p&gt;Mathilde hat andere Schmerzpunkte als ich; für sie sind das insbesondere
das schlechte Wetter,
die suboptimalen Arbeitsbedingungen
(Wochenend- &lt;em&gt;und&lt;/em&gt; Spätdienste bei gleichzeitig niedrigem Lohn) als wie auch
die eher bescheidene Qualität des Essens.
Und diese Liste ist bei weitem noch nicht vollständig.&lt;/p&gt;

&lt;p&gt;Insofern haben wir am Montag beschlossen, dass wir beide am liebsten
so bald wie möglich nach Österreich zurückkehren möchten.
Ich habe mich am Tag nach unserem großen Kriegsrat beim FWF gemeldet, um mich
nach der Möglichkeit einer Fortsetzung meiner Forschung in Österreich zu erkundigen.
Am Mittwoch erhielt ich eine sehr nette Antwort,
in der mir erklärt wurde, dass ich zwar aus steuerlichen Gründen
während meines Auslandsaufenthalts tatsächlich in den Niederlanden leben muss,
jedoch schon vorzeitig meine einjährige Rückkehrphase in Österreich antreten und
bis zu drei Monate meines Auslandsaufenthalts in die Rückkehrphase umwidmen könnte.
Das bedeutet, dass sich mein Forschungsprojekt von drei auf ca. zwei Jahre verkürzen würde.
Das ist zwar schade, aber dennoch kein Beinbruch, da ich die für mich
interessantesten Teile meines Projekts vermutlich in dieser Zeit fertigstellen kann.
Da unsere Rückkehr nach Österreich dennoch einiges an Vorbereitung erfordert,
gehe ich davon aus, dass unser eigentlicher Umzug erst so im Juni stattfinden wird.&lt;/p&gt;

&lt;p&gt;Seit wir diese Entscheidung getroffen haben, fühlen wir uns beide deutlich besser.
Wir haben so viele schöne Rückmeldungen von Freunden und Verwandten bekommen,
die sich über unsere geplante Rückkehr nach Tirol freuen,
dass wir uns noch mehr darauf freuen.&lt;/p&gt;

&lt;p&gt;Am Samstag habe ich erfahren, dass mein Artikel bei der Konferenz,
bei der ich ihn eingereicht habe, leider nicht akzeptiert wurde.
Bitter, aber ich kann ihn glücklicherweise in Kürze bei
&lt;a href=&quot;https://tableaux2021.org/&quot;&gt;einer anderen Konferenz&lt;/a&gt; einreichen,
wo er thematisch fast noch besser hinpasst.
Die nächste Zeit werde ich damit beschäftigt sein,
die Kommentare der Gutachter in den Artikel einzuarbeiten.&lt;/p&gt;

&lt;p&gt;Ich wünsche meiner Leserschaft eine schöne Woche und bis bald!&lt;/p&gt;

</description>
        <pubDate>Mon, 12 Apr 2021 00:00:00 +0000</pubDate>
        <link>http://gedenkt.at/amsterdam/besluit/</link>
        <guid isPermaLink="true">http://gedenkt.at/amsterdam/besluit/</guid>
        
        
        <category>amsterdam</category>
        
      </item>
    
  </channel>
</rss>
