<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Jonas Greitemann</title>
    <description>Jonas Greitemann
</description>
    <link>https://greitemann.dev/</link>
    <atom:link href="https://greitemann.dev/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 20 Feb 2024 14:42:08 +0000</pubDate>
    <lastBuildDate>Tue, 20 Feb 2024 14:42:08 +0000</lastBuildDate>
    <generator>Jekyll v3.9.5</generator>
    
      <item>
        <title>The C++ range adaptor pipe operator is associative</title>
        <description>&lt;p&gt;Tina Ulbrich (&lt;a href=&quot;https://twitter.com/_Yulivee_&quot;&gt;@_Yulivee_&lt;/a&gt;) recently gave her talk &lt;a href=&quot;https://www.youtube.com/watch?v=Ln_cVjJl680&quot;&gt;“How to Rangify Your Code”&lt;/a&gt; at my
local meetup, in which she gave a rundown of several examples from her codebase where loop-heavy code was replaced by
pipelines of range adaptors. I sunk my teeth into one of those from an API design perspective and show how it can be
generalized to work with generic ranges, based on the associative property of the pipe operator used to compose ranges
and range adaptors.&lt;/p&gt;

&lt;h3 id=&quot;tinas-sliding_mean-example&quot;&gt;Tina’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt; example&lt;/h3&gt;

&lt;p&gt;First off, Tina used the &lt;a href=&quot;https://github.com/ericniebler/range-v3&quot;&gt;range-v3&lt;/a&gt; library for most of her code samples as it supports more range adaptors
and consumers than the meager subset that was standardized for C++20. However, C++23 will improve the situation
significantly and MSVC (or rather the Microsoft STL) already has good enough support that I will use C++23 standard
ranges in this post.&lt;/p&gt;

&lt;p&gt;Now, one of the first examples Tina showed was the calculation of a sliding mean. The code that she started out with
iterated over a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt; of values with a raw loop and created arrays of five elements in each iteration which was than
passed into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt; function. The resulting means for each of the sliding windows were than pushed into a vector. She
then showed how you’d go about doing the same with ranges:&lt;/p&gt;

&lt;div class=&quot;language-cpp 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;constexpr&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&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;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.&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;rng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&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;auto&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sliding_mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&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;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&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;&lt;a href=&quot;https://godbolt.org/z/Kaf7W13Ka&quot;&gt;Godbolt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The ranges-based implementation has several advantages over the loop-based one: The size of the window is easily
changed; in fact, it could just be turned into a second parameter to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt; function. Additionally, the
original code would have needed to do bounds checking in case the input range is smaller than the window size; the
ranges code does that automatically and produces an empty vector in that case.&lt;/p&gt;

&lt;h3 id=&quot;generalizing-the-function-to-return-ranges&quot;&gt;Generalizing the function to return ranges&lt;/h3&gt;

&lt;p&gt;Tina already mentioned in her talk that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::ranges::to&amp;lt;std::vector&amp;gt;()&lt;/code&gt; is not even necessary, but she included
this to keep the function signature the same compared to the original implementation. If you relax this
requirement, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt; turns into a lazy algorithm and its result can be further adapted, e.g., by rounding the
window means to the nearest integer:&lt;/p&gt;

&lt;div class=&quot;language-cpp 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;constexpr&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sliding_mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_access_range&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&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;auto&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;round_to_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static_cast&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lround&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&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;int&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;4.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;5.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;4.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;4.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;5.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;9.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;7.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;mf&quot;&gt;8.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;6.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;5.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;4.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sliding_mean&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;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;round_to_int&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;&lt;a href=&quot;https://godbolt.org/z/rxPG956Go&quot;&gt;Godbolt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m using the {fmt} library here which has the ability to format ranges directly. To be clear, this would’ve worked with
the previous version as well but it would’ve meant that first the means are calculated and aggregated into a vector and
then, second, that vector would’ve been iterated, its elements rounded and the result would’ve been printed. Instead,
this version doesn’t need to allocate any memory for the intermediate vector and instead calculates the means, rounds
them, and prints the resulting integers in a single pass.&lt;/p&gt;

&lt;p&gt;You may also notice the funny-looking trailing return type. The &lt;em&gt;actual&lt;/em&gt; return type is some unwieldy thing like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slide_view&amp;lt;transform_view&amp;lt;span&amp;lt;double const&amp;gt;, ...&amp;gt;&amp;gt;&lt;/code&gt;. It is of course perfectly fine to
omit the return type altogether and have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; deduce it, but just like that’s often not the best idea for “normal”
functions with respect to readability, it is beneficial to constrain the return type with an appropriate range concept
to give the consumer of the API just the information they actually need to use it. I haven’t seen constrained return
types being used in the wild yet, but I hope they catch on as people get more comfortable with concepts as a tool for
understanding and documenting requirements rather than just as language support for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::enable_if&lt;/code&gt;. In this case, we
input a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::span&lt;/code&gt; which is a &lt;em&gt;contiguous&lt;/em&gt; range, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transform&lt;/code&gt; can only retain the &lt;em&gt;random access&lt;/em&gt; property.&lt;/p&gt;

&lt;p&gt;It should be noted that doing things lazily is not always more efficient and can easily lead to work being done twice.
One should be conscious of &lt;em&gt;where&lt;/em&gt; the actual work happens (inside of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fmt::print&lt;/code&gt; where the range is consumed) and that
saving the range itself as a local variable and using it multiple times only saves you from rebuilding the “expression
template” but does not cache the result of the calculation. If the latter is desired, the caller needs to follow up the
range with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to&amp;lt;std::vector&amp;gt;()&lt;/code&gt; at the call site to eagerly consume it and then share the result. From an API design
perspective, this leaves the decision between lazy and eager computation with the caller; that’s fine so long as they
are aware of the responsibility bestowed upon them which can be problematic when introducing this kind of thing to
legacy codebases where team members expect eager algorithms.&lt;/p&gt;

&lt;h3 id=&quot;generalizing-function-arguments-to-accept-ranges&quot;&gt;Generalizing function arguments to accept ranges&lt;/h3&gt;

&lt;p&gt;Tina’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt; is already great in that it accepts a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::span&lt;/code&gt;. That means that it can be called using
a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; or a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::array&lt;/code&gt;, a C-style array, or in general any range that is both &lt;em&gt;sized&lt;/em&gt; and &lt;em&gt;contiguous&lt;/em&gt;. That
is however still a pretty hefty requirement and rules out almost all the non-trivial range adaptors, as well as range
factories like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::views::iota&lt;/code&gt;. And it’s an unnecessary requirement at that, given &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::views::slide&lt;/code&gt; merely
requires a &lt;em&gt;forward&lt;/em&gt; range. To relax it, we need to turn &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt; into a template (here using C++20’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt;
template parameters):&lt;/p&gt;

&lt;div class=&quot;language-cpp 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;constexpr&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sliding_mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward_range&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward_range&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&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;Constraining the template with the appropriate concept is of course optional, but it helps with readability and fails
earlier. There’s a catch here, however: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt; so far also operated on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt;s which worked because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slide&lt;/code&gt; yields views
which are sized and themselves model the same range concept as the input range; i.e., when operating on a &lt;em&gt;contiguous&lt;/em&gt;
range (like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt;), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slide&lt;/code&gt; yields itself &lt;em&gt;sized&lt;/em&gt; and &lt;em&gt;contiguous&lt;/em&gt; ranges which are then implicitly convertible
to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt;s. Now that we relaxed the contiguity of the argument of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt;, we need to do the same for the
argument of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt;. Merely turning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt; into a function template doesn’t work either, as it cannot be passed as a
function reference to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::views::transform&lt;/code&gt; without specifying its template arguments which is difficult to do
portably. What does work is turning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mean&lt;/code&gt; into a function object with a generic call operator, e.g. by defining it as a
lambda:&lt;/p&gt;

&lt;div class=&quot;language-cpp 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;inline&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;constexpr&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sized_range&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&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;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;common&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.&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;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rng&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;Another detail here is that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;numeric&amp;gt;&lt;/code&gt; algorithms are not yet rangified, so we use C++17’s iterator version
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::reduce&lt;/code&gt;. That however requires both begin and end iterators to have the same type which is not true for some
range views, e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::views::filter&lt;/code&gt;. To fix this, the input range is first adapted into a &lt;em&gt;common&lt;/em&gt; range.&lt;/p&gt;

&lt;p&gt;With this, we are finally able to use our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt; with an input view which is itself a range pipeline,
where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fmt::print&lt;/code&gt; still consumes the range completely lazily but that now also includes the generation of the input
numbers themselves.&lt;/p&gt;

&lt;div class=&quot;language-cpp 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;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sliding_mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iota&lt;/span&gt;&lt;span class=&quot;p&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;mi&quot;&gt;30&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_even&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;round_to_int&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;&lt;a href=&quot;https://godbolt.org/z/MdYfW4W44&quot;&gt;Godbolt&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;composite-range-adaptors&quot;&gt;Composite range adaptors&lt;/h3&gt;

&lt;p&gt;While the above version is now functionally exactly where we want it to be, it looks pretty awkward. It would be much
nicer if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt; would support range pipelining:&lt;/p&gt;

&lt;div class=&quot;language-cpp 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;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&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;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sliding_mean&lt;/span&gt;
                     &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;round_to_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iota&lt;/span&gt;&lt;span class=&quot;p&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;mi&quot;&gt;30&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_even&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;sliding_mean&lt;/span&gt;
                   &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;round_to_int&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;Besides the fact that there’s something deeply satisfying about lining up the pipe operators, this also communicates
more clearly that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt; is merely adapting a range and is itself lazy. How might we implement support
for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator|&lt;/code&gt;? This is actually quite hard to do in general with the range facilities as they stand in C++20 without
adding to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std&lt;/code&gt; namespace, which is in fact undefined behavior. Fortunately, the situation is about to improve in
C++23 thanks to &lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2387r3.html&quot;&gt;Barry Revzin’s P2387&lt;/a&gt; which introduces the CRTP base class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::ranges::range_adaptor_closure&lt;/code&gt;.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt; function can then be replaced by the call operator of a function object &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean_fn&lt;/code&gt; which
derives from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;range_adaptor_closure&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cpp 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;nc&quot;&gt;sliding_mean_fn&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;range_adaptor_closure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sliding_mean_fn&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;constexpr&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward_range&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward_range&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&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;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;constexpr&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sliding_mean_fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sliding_mean&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;&lt;a href=&quot;https://godbolt.org/z/Ez3sG3MxM&quot;&gt;Godbolt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That works and is honestly not that much boilerplate. There exists however a much simpler way of achieving the same
effect which already works in C++20 (at least if you ignore that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slide&lt;/code&gt; is C++23) and relies on the fact that the pipe
operator for range adaptors is associative, meaning that given a range &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R&lt;/code&gt; and two range adaptors &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A₁&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A₂&lt;/code&gt;, the
expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R | A₁ | A₂&lt;/code&gt; can both be seen as the successive application of both adaptors, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(R | A₁) | A₂&lt;/code&gt;, or
equivalently as the application of a single combined adaptor, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R | (A₁ | A₂)&lt;/code&gt;. Hence, instead of defining
a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt; function which applies two adaptors to a generic range argument and then going to the motions of
turning that function into a range adaptor closure, we can simply combine both adaptors to yield the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sliding_mean&lt;/code&gt;
adaptor object directly!&lt;/p&gt;

&lt;div class=&quot;language-cpp 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;inline&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;constexpr&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sliding_mean&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&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;&lt;a href=&quot;https://godbolt.org/z/n3MnxKT4K&quot;&gt;Godbolt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is almost embarrassingly simple. Composing range adaptors in this way is akin to &lt;em&gt;point-free programming&lt;/em&gt; in
functional programming languages where functions are defined through composition and partial application (“currying”) of
other functions. The equivalent of currying is also possibly by creating a range adaptor factory function, e.g. to allow
specifying the window size:&lt;/p&gt;

&lt;div class=&quot;language-cpp 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;constexpr&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sliding_mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slide&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;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&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;&lt;a href=&quot;https://godbolt.org/z/7T7Mx6osj&quot;&gt;Godbolt&lt;/a&gt;&lt;/p&gt;

&lt;!--
### Comparison to Rust's `Iterator` trait

```rust
fn mean(slice: &amp;[f64]) -&gt; f64 {
    let len = slice.len() as f64;
    slice.into_iter().sum::&lt;f64&gt;() / len
}

fn sliding_mean(slice: &amp;[f64]) -&gt; impl Iterator&lt;Item=f64&gt; + '_ {
    slice.windows(5)
         .map(mean)
}
```

```rust
use itertools::Itertools;
let a = [3., 4., 5., 4., 3., 2., 4., 5., 9., 7.,
         8., 6., 5., 4., 3., 2., 0., 1., 2., 1.];
println!(&quot;[{}]&quot;, sliding_mean(&amp;a)
                 .map(f64::round)
                 .format(&quot;, &quot;));
```
[Godbolt](https://godbolt.org/z/3bEre38cf)



```rust
println!(&quot;[{}]&quot;, sliding_mean(a.into_iter())
                 .map(f64::round)
                 .format(&quot;, &quot;));
println!(&quot;[{}]&quot;, sliding_mean(0..15)
                 .map(f64::round)
                 .format(&quot;, &quot;));
```

[Godbolt: tuple impl](https://godbolt.org/z/9PWeThW9r)

Discussion on [itertools issue #64][itertools-issue-64]

```rust
fn mean&lt;I, T&gt;(iter: I) -&gt; f64
    where I: Iterator&lt;Item=T&gt; + ExactSizeIterator,
          T: Into&lt;f64&gt;,
{
    let len = iter.len() as f64;
    iter.map_into().sum::&lt;f64&gt;() / len
}

fn sliding_mean&lt;I, T&gt;(iter: I) -&gt; impl Iterator&lt;Item=f64&gt;
    where I: Iterator&lt;Item=T&gt; + ExactSizeIterator + Clone,
          T: Into&lt;f64&gt;,
{
    iter.slide(5)
        .map(mean)
}
```
[Godbolt](https://godbolt.org/z/E7EdrxMnj)

Would be nicer to simply chain function:

```rust
println!(&quot;[{}]&quot;, a.into_iter()
                  .sliding_mean()
                  .map(f64::round)
                  .format(&quot;, &quot;));
println!(&quot;[{}]&quot;, (0..15).sliding_mean()
                        .map(f64::round)
                        .format(&quot;, &quot;));
```

Using an extension trait with a blanket implementation:

```rust
trait SlidingMeanIterator: Iterator + ExactSizeIterator + Clone
    where &lt;Self as Iterator&gt;::Item: Into&lt;f64&gt;,
{
    fn sliding_mean(self)
        -&gt; Map&lt;Slide&lt;Self&gt;,
               fn(&lt;Slide&lt;Self&gt; as Iterator&gt;::Item) -&gt; f64&gt;
    {
        self.slide(5)
            .map(mean)
    }
}

impl&lt;I, T&gt; SlidingMeanIterator for I
    where I: Iterator&lt;Item=T&gt; + ExactSizeIterator + Clone,
          T: Into&lt;f64&gt;
{}
```
[Godbolt](https://godbolt.org/z/z7Gf6avEz)

[itertools-issue-64]: https://github.com/rust-itertools/itertools/issues/64
--&gt;

</description>
        <pubDate>Sun, 13 Nov 2022 13:37:28 +0000</pubDate>
        <link>https://greitemann.dev/2022/11/13/the-c-range-adaptor-pipe-operator-is-associative/</link>
        <guid isPermaLink="true">https://greitemann.dev/2022/11/13/the-c-range-adaptor-pipe-operator-is-associative/</guid>
        
        <category>c++</category>
        
        <category>algorithms</category>
        
        <category>functional</category>
        
        
      </item>
    
      <item>
        <title>EuroRust 2022 Trip Report</title>
        <description>&lt;p&gt;This fall, I attended the first-ever &lt;a href=&quot;https://eurorust.eu/&quot;&gt;EuroRust&lt;/a&gt;, the European offshoot of Rustfest, in Berlin. The conference
was fairly small (but sold out) with just two days and a single track, yet the talks were all pretty high-quality. Since
the Rust community is quite small and full-time Rust jobs are still in short supply, it was interesting talking to
people who managed to work in one. I had a great time in Berlin; the organizers were very professional, the venue was
appropriately industrial, food and coffee (!) were great, and it was all rounded out by a delightful closing dinner on a
boat on the Spree river. In short, I’m already looking forward to next year’s edition.&lt;/p&gt;

&lt;p&gt;Below, I’ve collected my impressions of some of the talks, grouped by their overarching topics.&lt;/p&gt;

&lt;h2 id=&quot;integration-and-interop-with-other-languages&quot;&gt;Integration and interop with other languages&lt;/h2&gt;

&lt;p&gt;Few people get the chance to start a greenfield project at work, let alone in Rust; for most projects and products, the
aim is to start using Rust in some fairly small corner where it can play out its strengths, be it performance or safety,
and gradually expand its scope from there. The headline story in this context in recent months certainly was Rust being
used inside the Linux kernel, but an arguably even more pervasive piece of software which underpins billions of devices,
is libcurl. Its maintainer, &lt;a href=&quot;https://eurorust.eu/2022/speakers/daniel-stenberg/&quot;&gt;Daniel Stenberg&lt;/a&gt;, gave the opening keynote and presented the architecture of
libcurl which provides several C interfaces for HTTP 1/2/3, QUIC, and TLS backends, all of which have implementations in
Rust, based on the &lt;a href=&quot;https://crates.io/crates/hyper&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hyper&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://crates.io/crates/quiche&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;quiche&lt;/code&gt;&lt;/a&gt;, and &lt;a href=&quot;https://crates.io/crates/rustls&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustls&lt;/code&gt;&lt;/a&gt; crates, respectively. Neither one is
feature-complete at this point, and it’ll be awhile until downstream projects start shipping libcurl with the Rust
backends by default, but I’m amazed that a library as well established as libcurl dares to build on top of, say, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hyper&lt;/code&gt;
and the underlying Tokio runtime. Vice versa, libcurl’s requirements can inform the development of new APIs in those
crates, as well as the Rust language at large.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://eurorust.eu/2022/speakers/colin-finck/&quot;&gt;Colin Finck&lt;/a&gt;, who’s a contributor in the &lt;a href=&quot;https://reactos.org/&quot;&gt;React OS&lt;/a&gt; project which aims to reverse-engineer a
binary-compatible clone of MS Windows, presented on his crate &lt;a href=&quot;https://crates.io/crates/nt-list&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nt-list&lt;/code&gt;&lt;/a&gt; which comes with an ABI compatible
implementation of Windows Linked Lists in Rust. He highlighted some of the challenges that arise from the need to copy
the memory layout of the intrusive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LIST_ENTRY&lt;/code&gt; node and how to overcome those in safe Rust. The resulting
implementation prevents most of the common misuses of the original C implementation while retaining binary compatibility
which allows using them to write Windows drivers or to browse their contents in WinDbg, even with versions predating
Rust itself.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://eurorust.eu/2022/speakers/raphael-gomes/&quot;&gt;Raphaël Gomès&lt;/a&gt; reported on how the &lt;a href=&quot;https://www.mercurial-scm.org/&quot;&gt;Mercurial VCS&lt;/a&gt; has been rewriting some of its Python codebase in
Rust. He went over some of the challenges, from technical issues related to encodings and testing, to human ones, like
building Rust experience in a team of Python devs. While the learning curve has been steep and bumpy at times, he
surmised that introducing Rust has been beneficial not just for the head-spinning performance improvements of 20,000x in
some cases, but also in terms of developer productivity.&lt;/p&gt;

&lt;p&gt;While many of the Rust integrations rest on the FFI to C, interoperating with higher-level languages can be a bit more
of a challenge. As a C++ developer in my day job, Rust’s interop story with C++ was of particular interest to
me. &lt;a href=&quot;https://eurorust.eu/2022/speakers/tobias-hunger/&quot;&gt;Tobias Hunger&lt;/a&gt; reviewed several approaches, from calling member functions of C++ classes from within Rust
(and vice versa) using the &lt;a href=&quot;https://crates.io/crates/cxx&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cxx&lt;/code&gt;&lt;/a&gt; crate, including automatic translation between certain library types
like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::unique_ptr&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::vector&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; to Rust counterparts, to writing inline C++ code within a Rust
function using the &lt;a href=&quot;https://crates.io/crates/cpp&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cpp&lt;/code&gt;&lt;/a&gt; crate. Tobias also briefly touched on how C++ libraries can be integrated into Cargo
projects and how Rust code can be built from a CMake project using &lt;a href=&quot;https://github.com/corrosion-rs/corrosion&quot;&gt;Corrosion&lt;/a&gt;. I was pleasantly surprised by
what is possible in this space, esp. in the context of the current craze around C++ successor languages
like &lt;a href=&quot;https://github.com/carbon-language/carbon-lang&quot;&gt;Carbon&lt;/a&gt;, which actually recommends to use Rust for new projects and pitches itself as an option for
seamless interop with legacy C++ codebases. I wonder if an investment into Rust interop wouldn’t be more fruitful than
building another memory-unsafe language from scratch.&lt;/p&gt;

&lt;p&gt;Last but not least in this category, there was a talk by &lt;a href=&quot;https://eurorust.eu/2022/speakers/bogdan-kolbik/&quot;&gt;Bogdan Kolbik&lt;/a&gt; about interop with the JVM from an
application written in Scala. While it is possible to call into native code from the JVM using the JNI, they ended up
passing Protobuf messages between Rust and Scala code. It would be interesting to know how JetBrains does interop
between Kotlin, another JVM language, and the Rust backend in their new &lt;a href=&quot;https://blog.jetbrains.com/fleet/2022/01/fleet-below-deck-part-i-architecture-overview/&quot;&gt;Fleet&lt;/a&gt; IDE, but I suspect it will be a
similar story, given that Fleet’s backend can run remotely as well.&lt;/p&gt;

&lt;h2 id=&quot;rust-and-the-web&quot;&gt;Rust and the Web&lt;/h2&gt;

&lt;p&gt;While in C++ circles, Rust is perceived mainly as a competitor systems programming language, a lot of the interest in
Rust is actually coming from the massive web development community. This is attested to by Mainmatter, a Munich-based
web consultancy, who presented EuroRust and publicized what they call a &lt;a href=&quot;https://mainmatter.com/blog/2022/10/12/making-a-strategic-bet-on-rust/&quot;&gt;“strategic bet on Rust”&lt;/a&gt; at the
start of the conference. In this space, there are mainly two areas where Rust is becoming increasingly popular: Using
Rust in the server backend to replace web frameworks like Rails, as well as compiling Rust to WebAssembly to run in the
browser. Of course, both of these can be combined in the same application to convey some of the same benefits that made
Node.js popular, i.e. sharing code between client and server side, and WASM itself can be executed server-side as well,
either through Node.js or for instance &lt;a href=&quot;https://wasmtime.dev/&quot;&gt;wasmtime&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the first front, server-side web frameworks, Rust developers are increasingly spoiled for
choice. &lt;a href=&quot;https://eurorust.eu/2022/speakers/rainer-stropek/&quot;&gt;Rainer Stropek&lt;/a&gt; did a good job reviewing and comparing four of them: &lt;a href=&quot;https://crates.io/crates/actix-web&quot;&gt;Actix-web&lt;/a&gt;,
&lt;a href=&quot;https://crates.io/crates/rocket&quot;&gt;Rocket&lt;/a&gt;, &lt;a href=&quot;https://crates.io/crates/warp&quot;&gt;Warp&lt;/a&gt;, and &lt;a href=&quot;https://crates.io/crates/axum&quot;&gt;Axum&lt;/a&gt;. He implemented the same simple API in each of them and gave the
audience a feel for their respective approaches. While Rocket seems to be the most ergonomic of the bunch with its
“magic” proc macro routes and being pitched as “batteries-included”, personally I like the tradeoffs chosen by the
newcomer Axum best as it is built on top of &lt;a href=&quot;https://crates.io/crates/tower&quot;&gt;Tower&lt;/a&gt;, Tokio’s middleware ecosystem, and ditches macros in favor of
still-readable-yet-not-quite-as-magic builder patterns.&lt;/p&gt;

&lt;p&gt;On the WebAssembly side of things, &lt;a href=&quot;https://eurorust.eu/2022/speakers/francois-mockers/&quot;&gt;François Mockers&lt;/a&gt; showed how games written using the &lt;a href=&quot;https://bevyengine.org/&quot;&gt;Bevy&lt;/a&gt; engine
can be compiled into WASM. His talk was somewhat in the same vein as the one by Ólafur Waage
&lt;a href=&quot;/2022/08/07/cpp-on-sea-2022-trip-report&quot;&gt;back at C++ on Sea&lt;/a&gt; who showed how to accomplish the same thing in C++, albeit without the benefit of
a feature-rich engine such as Bevy. Subsequently, &lt;a href=&quot;https://eurorust.eu/2022/speakers/alberto-schiabel/&quot;&gt;Alberto Schiabel&lt;/a&gt; dove a little more into technical details
on the secret sauce which makes the integration of Rust into a JS app relatively smooth, but also showed some of the
limitations that (still) exist.&lt;/p&gt;

&lt;h2 id=&quot;case-studies&quot;&gt;Case studies&lt;/h2&gt;

&lt;p&gt;There’s just something deeply satisfying in starting out with a long spaghetti-code function and iteratively refactoring
it until it fits comfortably on a single slide. That’s exactly what &lt;a href=&quot;https://eurorust.eu/2022/speakers/stefan-baumgartner/&quot;&gt;Stefan Baumgartner&lt;/a&gt; did in this talk
“Trails, traits, and tribulations”. While some of this is just the application of common sense and recognizing where the
responsibility of one function ends and that of another starts, Stefan also had some advice specific to Rust, like using
the ?-operator to focus the function on the happy path and how implementing standard library traits for your own types
helps you identify those responsibilities and leads to more idiomatic code, meanwhile promoting code reuse, e.g. by
implementing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Display for Foo&lt;/code&gt; instead of writing a function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;print_foo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://eurorust.eu/2022/speakers/rafael-epplee/&quot;&gt;Rafael Epplée&lt;/a&gt; gave an account of how he went about end-to-end testing a web backend, though I found that most
of what he presented carries over to other types of application you’d want to write tests for (which should be all of
them!), be it integration tests or unit tests. In Rust, the story really isn’t any different from how you’d go about it
in other languages: abstract over the unit’s interactions with the outside world (filesystem, databases, other program
units which are tested separately) with a trait, and inject a fake test implementation which can be used to verify the
expected effects but doesn’t depend on the actual environment, thus giving you fast, parallel, and reproducible tests.
Rust’s trait system is uniquely suited for this task as it allows implementing the trait also on foreign types, thus
eliminating the need for a wrapper around third-party dependencies. Rafael also introduced the &lt;a href=&quot;https://crates.io/crates/rstest&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rstest&lt;/code&gt;&lt;/a&gt; crate
which I have since started using myself as it provides support for test fixtures, parametrized tests, and more.&lt;/p&gt;

&lt;p&gt;A colleague of mine at MVTec, &lt;a href=&quot;https://eurorust.eu/2022/speakers/lukas-bergdoll/&quot;&gt;Lukas Bergdoll&lt;/a&gt;, set out on a journey to optimize Rust’s existing stable sort
implementation and took the audience along to witness the mistakes he made on the way and shared his learnings. Overall,
it served as a humble reminder to always re-check your assumptions when confronted with surprising results. It takes
some courage to admit that you’re wrong, let alone to turn that into a talk. Here’s to hoping that his work might still
make it into the standard library.&lt;/p&gt;

&lt;h2 id=&quot;governance-and-organizations&quot;&gt;Governance and Organizations&lt;/h2&gt;

&lt;p&gt;This last cluster of topics focussed less on the language itself but rather on the people and processes that drive its
progress. Recent events and discussions about the future of C++ pointed out the shortcomings of its ISO process and
many see Carbon’s biggest advantage over C++ in its open-source process for evolving the language (draft) which is
inspired by the likes of Swift and Rust. Hence, I was interested in how the Rust project’s governance model actually
works and &lt;a href=&quot;https://eurorust.eu/2022/speakers/ryan-levick/&quot;&gt;Ryan Levick&lt;/a&gt; gave a pretty good overview of its structure and processes in his keynote at the start
of the second day. The day before, &lt;a href=&quot;https://eurorust.eu/2022/speakers/pietro-albini/&quot;&gt;Pietro Albini&lt;/a&gt;, who heads the Rust Security Response WG, walked through the
lifecycle of a particular CVE and shed some light on the sensitive work that by definition has to happen behind closed
doors.&lt;/p&gt;

&lt;p&gt;The first day concluded with a panel discussion, moderated by the Rust Foundation’s CEO, &lt;a href=&quot;https://eurorust.eu/2022/speakers/rebecca-rumbul/&quot;&gt;Rebecca Rumbul&lt;/a&gt;, with
representatives from four companies which are using Rust. An interesting takeaway was that the market for Rust
developers is still pretty much inverted from the labor market at large, both because Rust is popular with developers,
but also because companies are still reluctant and careful to migrate projects to (or start projects in) Rust. And when
they do, they typically start with a small team of veteran engineers; few companies are willing to take the risk of
trusting a new hire with a project using a technology they don’t have experience with — that’s one unknown too many.
Thus, for folks who wish to use Rust professionally, the panel recommended to try to push for Rust at work when the
chance presents itself, to find some niche where Rust can be integrated and play out its strengths, and then to talk
about it, at conferences, in blog posts, on Twitter, to make the industry see that placing the bet on Rust may not be as
risky as it might seem.&lt;/p&gt;

</description>
        <pubDate>Sat, 29 Oct 2022 21:58:48 +0000</pubDate>
        <link>https://greitemann.dev/2022/10/29/eurorust-2022-trip-report/</link>
        <guid isPermaLink="true">https://greitemann.dev/2022/10/29/eurorust-2022-trip-report/</guid>
        
        <category>rust</category>
        
        <category>c++</category>
        
        <category>wasm</category>
        
        <category>conference</category>
        
        
      </item>
    
      <item>
        <title>C++ on Sea 2022 Trip Report</title>
        <description>&lt;p&gt;I had a chance to attend “C++ on Sea” in Folkestone this year. This write-up aims to give an overview of my personal
highlights as well as some solid overview talks.&lt;/p&gt;

&lt;h2 id=&quot;highlights&quot;&gt;Highlights&lt;/h2&gt;

&lt;h3 id=&quot;jason-turner-making-c-fun-safe-and-accessible&quot;&gt;&lt;a href=&quot;https://youtu.be/HlaoxhmThmk&quot;&gt;Jason Turner: Making C++ fun, safe, and accessible&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Jason gave the closing plenary talk of the conference, dubbed “endnote”, and this was announced as his “most interactive
talk” yet which says a lot if you know his style. However, it started out perfectly silent with him putting up slides
with code in a made-up language with gibberish keywords and unfamiliar syntax, prompting the audience to infer what the
code would do and by extension learn a new language. This was later revealed as a pitch for a project to develop
resources to teach C++ to people (and particularly children) who don’t speak English (yet) to make it more accessible.&lt;/p&gt;

&lt;p&gt;As for whether C++ as a language is safe, he showed a code snippet with several bugs and demonstrated how using the
right tools, modern compilers will suggest how to make the code compile, sanitizers can spot memory errors among other
things, and static analyzers will nudge you in the way of best practices. These tools can be difficult to set up
properly (as even our build systems have the wrong defaults) and Jason promoted his best-practice CMake starter projects
on Github which come with full sanitizers and static analyzers running in CI on day one.&lt;/p&gt;

&lt;h3 id=&quot;daniela-engert-contemporary-c&quot;&gt;&lt;a href=&quot;https://youtu.be/J_1-Au2MX6Y&quot;&gt;Daniela Engert: Contemporary C++&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Daniela’s talk was dominated largely by her scrolling through a toy project (which is already on her Github) which is a
simple client/server architecture where the server reads GIFs from a directory and writes their frames to socket;
whereas the client reads the images and displays them in a GUI. This was accomplished through liberate use of
coroutines: iterating the directory using a generator, reading the GIFs from disk, and running the server — all done
asynchronously but without spawning any dedicated threads. Instead, she plugged the coroutines into each other and
scheduled the whole thing on a thread pool provided by the ASIO library, meaning that she could just as well run the
whole app just on a single thread, without ever blocking on I/O operations. Even though the presentation of the code was
a bit dry at times, this was a really impressive demo how to use coroutines in practice and how they have the potential
to revamp and simplify our architectures, removing the need for synchronization completely and thus eliminating entire
species of bugs.&lt;/p&gt;

&lt;p&gt;Daniela also showed off the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::stop_source&lt;/code&gt; for cooperative cancellation (standalone, without
using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::jthread&lt;/code&gt;) to shut the server down cleanly, and generally wrapped all her dependencies in modules which
re-export the bits she needed.&lt;/p&gt;

&lt;h3 id=&quot;jonathan-müller-coroutines-in-c-vs-rust&quot;&gt;&lt;a href=&quot;https://youtu.be/yt-gueRNCTU&quot;&gt;Jonathan Müller: Coroutines in C++ vs. Rust&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;I was looking forward to this talk ever since the programme was announced. Same as C++, Rust gained language support for
coroutines (more commonly just referred to as “async/await”) fairly recently and both languages went for a “stackless”
approach (contrary to Go’s “Goroutines” which are stackful). Otherwise, they went for quite different approaches.&lt;/p&gt;

&lt;p&gt;In C++, a coroutine looks like a regular function but has to contain one of the new keywords &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;co_await&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;co_return&lt;/code&gt;, or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;co_yield&lt;/code&gt; . The return type of the function is not the “logical” return type which is “returned” through co_return or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;co_yield&lt;/code&gt; , but a coroutine type like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::generator&lt;/code&gt;  (coming in C++23) which customises the behaviour of the coroutine
through its associated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;promise_type&lt;/code&gt; and is usually templated on the logical return type. Rust coroutines are more
obvious to spot from the function declaration as they are functions prefixed with the async keyword. There’s no special
syntax to return from them, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;co_await x&lt;/code&gt; is spelled &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x.await&lt;/code&gt;, and there is no way to yield values from them.&lt;/p&gt;

&lt;p&gt;There are also notable differences in how the memory associated with a coroutine is managed. A C++ coroutine’s internal
state machine resides in a compiler generated type, the coroutine frame, which is inaccessible to the programmer who
interacts with it solely through a type-erased handle. For that reason, the coroutine frame is technically always
heap-allocated, though that allocation may be elided in some cases. In contrast, the state machine type powering Rust’s
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt; functions (which implements the Future trait) is either entirely compiler-generated, or can be entirely
hand-written and its type can be named and is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sized&lt;/code&gt;. This gives Rust programmers control over how they want to store
the coroutine, including on the stack when practical, but also means that the type must be known to the compiler
frontend which prevents the backend from optimising away unused members.&lt;/p&gt;

&lt;p&gt;I’ll definitely have to rewatch the talk after I have played around with coroutines in both languages more. Jonathan
talks quite fast and the subject is not easy so all of us came out of that talk with our heads spinning. My impression
is that C++’s approach is overall probably a bit more efficient and flexible; I’m just wondering if that is worth it,
considering that Rust’s async functions seem more accessible, particularly to programmers coming from e.g. Javascript
where working with async/await is common practice.&lt;/p&gt;

&lt;h2 id=&quot;honourable-mentions&quot;&gt;Honourable mentions&lt;/h2&gt;

&lt;h3 id=&quot;hana-dusíková-lightning-updates&quot;&gt;&lt;a href=&quot;https://youtu.be/f5o42_bMidg&quot;&gt;Hana Dusíková: Lightning Updates&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Hana gave the opening keynote of the conference, presenting a soon-to-be-open-sourced library to manage update
mechanisms with possibly complex update path graphs. This was an interesting case study in API design, showing off many
of the new features coming in C++23 along the way. Working at Avast, the natural example for this are Anti-Virus
definitions which need frequent updates but shouldn’t guzzle too much bandwidth. However, towards the end she showed how
the updater can be customized to draw its update data from the filesystem, effectively turning her library into a simple
VCS.&lt;/p&gt;

&lt;h3 id=&quot;andrew-soffer-how-hard-could-it-be-lessons-learned-from-replacing-int64-with-int64_t&quot;&gt;&lt;a href=&quot;https://youtu.be/NPHO3bhQ3G8&quot;&gt;Andrew Soffer: How Hard Could It Be? Lessons Learned from Replacing int64 With int64_t.&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Andrew gave an account of what it took to refactor Google’s entire codebase to replace Google’s own typedef &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64&lt;/code&gt; with
the standard &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64_t&lt;/code&gt;. Even when only considering x86_64 Linux as the target architecture, this turned out much harder
than one might expect even though both types represent the same idea, have identical binary representations, and are
implicitly interconvertible. Still, both typedefs alias distinct types (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;long&lt;/code&gt; vs. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;long long&lt;/code&gt;) which has implications for
overload resolution of function templates, as well as type specifiers in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printf&lt;/code&gt;-style format strings.&lt;/p&gt;

&lt;p&gt;The sheer size of Google’s codebase (about 250 million lines) means that manual refactorings just don’t scale. Instead,
he stressed the importance of automatic refactorings using clang-based tools and how an almost full unit test coverage
is essential to confidently commit changes too large for any human to review.&lt;/p&gt;

&lt;h3 id=&quot;ólafur-waage-sandbox-games--using-webassembly-and-c-to-make-a-simple-game&quot;&gt;&lt;a href=&quot;https://youtu.be/5dcqJF0pZk0&quot;&gt;Ólafur Waage: Sandbox Games — Using WebAssembly and C++ to make a simple game&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;It’s been more than four years since I last worked with C++ compiled into WebAssembly using the Emscripten toolchain, so
I was curious to see how the tooling improved, esp. given that Rust has been leading the way in terms of WASM support
recently. Emscripten now targets WASM by default (as opposed to asm.js) and bindings for C++ data structures and
functions can be defined through macros in the emscripten.h header which is a huge improvement from the raw shared
memory access I was familiar with, though it’s nowhere near as convenient as Rust’s bindgen.&lt;/p&gt;

&lt;p&gt;In terms of tooling, Ólafur demonstrated how the built-in (Javascript) debugger in Chrome and Firefox can be used to
debug and profile WASM, including setting breakpoints in C++ code or viewing flame graphs. Additionally, standalone WASM
runtimes allow using WebAssembly also outside of the browser similar to Node.js, or they can be embedded to create
portable plug-in infrastructures.&lt;/p&gt;

&lt;h2 id=&quot;good-overview-talks&quot;&gt;Good overview talks&lt;/h2&gt;

&lt;h3 id=&quot;anthony-williams-an-introduction-to-multithreading-in-c20&quot;&gt;&lt;a href=&quot;https://youtu.be/8mt076AtqYg&quot;&gt;Anthony Williams: An introduction to multithreading in C++20&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Anthony is responsible for many of the multithreading features in C++ and gave a good overview of latches, barriers,
futures, mutexes, semaphores, and atomics — and why should reach for them in that order. He also explained how the
cooperative cancellation API and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::jthread&lt;/code&gt; can help treat dedicated threads as value types.&lt;/p&gt;

&lt;h3 id=&quot;bryce-adelstein-lelbach-standard-parallelism&quot;&gt;&lt;a href=&quot;https://youtu.be/cCOABV97zfA&quot;&gt;Bryce Adelstein Lelbach: Standard Parallelism&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Bryce gave an introduction into the “senders and receivers” proposal which will hopefully be accepted for C++26. If so,
it will deliver on the final two “pillars” of standard parallelism, the first one being the C++ 17 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ExecutionPolicy&lt;/code&gt;
overloads of standard algorithms. In the second part of the talk, Bryce then presented &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::mdspan&lt;/code&gt;, which is now almost
certainly coming in C++23, and gave an outlook how it may tie into the various linear algebra proposals.&lt;/p&gt;

&lt;h3 id=&quot;mateusz-pusz-sneak-peek-c23&quot;&gt;Mateusz Pusz: Sneak Peek C++23&lt;/h3&gt;

&lt;p&gt;Mateusz’s talk went over all the new features that made it into C++23 so far. In particular, he spent quite a bit of
time on “deducing this” which will reduce the amount of boilerplate code library authors will need to write and will
make CRTP obsolete. &lt;em&gt;Update: Unfortunately, the video of this talk is not available on Youtube. There may have been a
problem with the recording.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;closing-remarks&quot;&gt;Closing remarks&lt;/h2&gt;

&lt;p&gt;This being my first C++ conference I was curious how the experience would compare to academic (physics) conferences and
how much of a difference it would make to attend in person as compared to watching the recording on Youtube. It is
definitely something else to sit in a Jason Turner talk for real. I also didn’t find the more technical talks as
exhausting as watching them on Youtube. This was helped by the fact that the programme had plenty of coffee breaks.
Those are sometimes referred to as the “hallway track” and I found it easy to engage in conversation with other people
as this was the first conference for many of them. Lastly, I was pleasantly surprised by how diverse and inclusive the
conference was.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;/assets/img/folkestone_beach.jpg&quot; alt=&quot;View from the conference venue, overlooking the English channel with the Frensh coastline on the horizon.&quot; width=&quot;70%&quot; /&gt;

&lt;figcaption&gt;&lt;p&gt;View from the conference venue, overlooking the English channel with the Frensh coastline on the horizon.&lt;/p&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

</description>
        <pubDate>Sun, 07 Aug 2022 13:04:49 +0000</pubDate>
        <link>https://greitemann.dev/2022/08/07/cpp-on-sea-2022-trip-report/</link>
        <guid isPermaLink="true">https://greitemann.dev/2022/08/07/cpp-on-sea-2022-trip-report/</guid>
        
        <category>c++</category>
        
        <category>wasm</category>
        
        <category>conference</category>
        
        
      </item>
    
      <item>
        <title>Joining MVTec</title>
        <description>&lt;p&gt;Besides prepping for the defense of &lt;a href=&quot;https://nbn-resolving.org/urn:nbn:de:bvb:19-250579&quot;&gt;my thesis&lt;/a&gt;, I spent most of the past few months scouring the job market in Munich. To that end, I’ve made a habit of attending the &lt;a href=&quot;https://www.meetup.com/MUCplusplus/&quot;&gt;MUC++ meet-up&lt;/a&gt; to get a peek into different companies using C++ in and around Munich. The line-up of speakers at those meetings is quite impressive and I will certainly keep going whenever possible.&lt;/p&gt;

&lt;p&gt;It is through these meet-ups that I became aware of &lt;a href=&quot;https://www.mvtec.com/&quot;&gt;MVTec&lt;/a&gt;, a local software company specializing in machine vision with a focus on industrial applications. After a quick round of interviews, I’ve accepted an offer for a position as Software Architect working on their MERLIC product, starting today.&lt;/p&gt;

&lt;p&gt;I’m very excited to embark on this next step in my career.
Naturally, I am not at liberty to discuss any details of my work in the same manner as I did during my PhD. Still, I expect to be able to keep this blog going, highlighting some of the C++ tidbits I’ll come across or side projects that I may or may not have time for.
Any and all opinions voiced on this website remain my own and are in no way affiliated with MVTec.&lt;/p&gt;

</description>
        <pubDate>Mon, 02 Dec 2019 06:32:07 +0000</pubDate>
        <link>https://greitemann.dev/2019/12/02/joining-mvtec/</link>
        <guid isPermaLink="true">https://greitemann.dev/2019/12/02/joining-mvtec/</guid>
        
        <category>meta</category>
        
        
      </item>
    
      <item>
        <title>Version 3 release of TK-SVM — Wrapping up</title>
        <description>&lt;p&gt;A new version of the TK-SVM framework has just been released and is now
available on the university’s GitLab repository. In keeping with the number of
SVM-related papers we have published in the past 1.5 years, this is version 3
and reflects the changes made to the framework to facilitate our &lt;a href=&quot;/publications/1907.12322/&quot;&gt;latest
paper&lt;/a&gt;, studying the XXZ model on the pyrochlore lattice.&lt;/p&gt;

&lt;p class=&quot;centered&quot;&gt;&lt;a href=&quot;https://gitlab.physik.uni-muenchen.de/LDAP_ls-schollwoeck/svm-order-params&quot; class=&quot;gitlab&quot;&gt;svm-order-params&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This release brings about a larger selection of sweep policies, more flexibility
in combining data from different runs, a &lt;a href=&quot;https://gitlab.physik.uni-muenchen.de/LDAP_ls-schollwoeck/svm-order-params/tree/v3.0/frustmag&quot;&gt;new client code&lt;/a&gt; for generic
classical frustrated spin systems, a new MPI-based parallelization model,
infrastructure for parallel tempering, many extensions to the simple graph
analysis introduced in the previous version, and countless bug fixes. A
comprehensive &lt;a href=&quot;https://gitlab.physik.uni-muenchen.de/LDAP_ls-schollwoeck/svm-order-params/blob/v3.0/CHANGELOG.md&quot;&gt;changelog&lt;/a&gt; is also available.&lt;/p&gt;

&lt;p&gt;More information on the TK-SVM method is now also publically available in my
&lt;a href=&quot;https://nbn-resolving.org/urn:nbn:de:bvb:19-250579&quot;&gt;PhD thesis&lt;/a&gt;, including an (otherwise unpublished) application to the
Heisenberg model on the Kagome lattice.
This wraps up my involvement with the TK-SVM project, even though this work will
very much continue without me.&lt;/p&gt;

</description>
        <pubDate>Sun, 01 Dec 2019 22:17:04 +0000</pubDate>
        <link>https://greitemann.dev/2019/12/01/wrapping-up-my-phd-project/</link>
        <guid isPermaLink="true">https://greitemann.dev/2019/12/01/wrapping-up-my-phd-project/</guid>
        
        <category>physics</category>
        
        <category>thesis</category>
        
        <category>machine-learning</category>
        
        <category>c++</category>
        
        
      </item>
    
      <item>
        <title>Frustrated magnetism: Thesis motivation</title>
        <description>&lt;h4 id=&quot;from-water-to-spin-ice&quot;&gt;From water to spin ice&lt;/h4&gt;

&lt;p&gt;Frustration is ubiquitous in nature.
So much so that the properties of water, including its unusually high melting and boiling points, its large heat capacity, latent heat, and anomalous density curve—all crucial for the development of life as we know it—are all consequences of frustration.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;/assets/img/WaterIce5.png&quot; alt=&quot;Figure 1: A configuration of five water molecules obeying the ice rules: each oxygen is covalently bound to two hydrogens and exactly one hydrogen sits between any two neighboring oxygens.&quot; width=&quot;50%&quot; class=&quot;&quot; /&gt;

&lt;figcaption&gt;&lt;p&gt;Figure 1: A configuration of five water molecules obeying the ice rules: each oxygen is covalently bound to two hydrogens and exactly one hydrogen sits between any two neighboring oxygens.&lt;/p&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;It is well known that the hydrogen atoms in \(\mathrm{H_2O}\) span an angle of about \(104^\circ\), slightly less than the \(109^\circ\) corresponding to the unperturbed tetrahedral coordination of hybridized \(sp^3\) orbitals of the central oxygen atom.
This leads to a nonvanishing dipolar moment due to the partial charges induced by the larger electronegativity of oxygen as compared to hydrogen.
In water ice (specifically the ice \(\mathrm{I}_h\) phase formed under terrestrial conditions), the molecules are arranged in a lattice with close to tetrahedral bond angles as well.
Due to the partial charges, it is energetically favorable for exactly one hydrogen to sit between any neighboring oxygen atoms, being covalently bound to one of them and forming a weak “hydrogen” bond with the other.
The orientation of the water molecules in the lattice is then determined by the Bernal-Fowler “ice rules” [&lt;a href=&quot;#ref-1&quot;&gt;1&lt;/a&gt;] which state that each molecule should be faced by the hydrogen atoms of two of its neighbors and the oxygen sides of the other two.
An example of a configuration respecting these ice rules is shown in Fig. 1.&lt;/p&gt;

&lt;p&gt;The ice rules do not uniquely determine the ground-state configuration of water ice. Rather, the number of compatible configurations, &lt;em&gt;i.e.&lt;/em&gt; the degeneracy of the ground state, grows exponentially with system size.
This then gives rise to an extensive contribution to the residual entropy which was famously estimated by Pauling as \(S_0/n = \ln(3/2) R\approx 3.4\,\mathrm{J}/(\mathrm{mol\,K})\) [&lt;a href=&quot;#ref-2&quot;&gt;2&lt;/a&gt;].
The extensive residual entropy consequently affects the thermodynamics of bulk properties and leads to the above anomalies associated with water.
An exponential ground-state degeneracy is one of the hallmarks of frustrated systems.
Somewhat sloppily, it is more commonly referred to as an extensive ground state degeneracy (exGSD) because it gives rise to an extensive residual entropy.&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;/assets/img/SpinIce5.png&quot; alt=&quot;Figure 2: The equivalent spin ice configuration on a pyrochlore lattice. For each tetrahedral cluster, two spins are pointing inwards and two are pointing outwards.&quot; width=&quot;50%&quot; class=&quot;&quot; /&gt;

&lt;figcaption&gt;&lt;p&gt;Figure 2: The equivalent spin ice configuration on a pyrochlore lattice. For each tetrahedral cluster, two spins are pointing inwards and two are pointing outwards.&lt;/p&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;An analogous situation is realized in a class of magnetic systems which—for this reason—are known as spin ices.
Experimental realizations of spin ices have been discovered in the rare-earth oxide materials \(\mathrm{Ho_2Ti_2O_7}\) [&lt;a href=&quot;#ref-3&quot;&gt;3&lt;/a&gt;] and \(\mathrm{Dy_2Ti_2O_7}\) [&lt;a href=&quot;#ref-4&quot;&gt;4&lt;/a&gt;,&lt;a href=&quot;#ref-5&quot;&gt;5&lt;/a&gt;].
In these compounds, only the rare-earth ions (\(\mathrm{Ho}^{3+}\) and \(\mathrm{Dy}^{3+}\)) are magnetic.
These form a pyrochlore lattice, a network of corner-sharing tetrahedra; its geometry is depicted in Fig. 2.
Due to a strong crystal-field anisotropy along the axis connecting the centers of tetrahedra, the magnetic moments behave as Ising spins.
The energy of such a configuration is then minimized if within each of the tedrahedra, two of the spins point inwards, while the other two point outwards.
This “two-in-two-out” rule is the spin-ice analogue of the ice rules in water.
Indeed, Fig. 2 depicts a configuration obeying the two-in-two-out rule which is equivalent to the water ice configuration in Fig. 1 by having the spins in the former point towards the location of each of the hydrogen atoms in the latter.
The residual entropy of \(\mathrm{Dy_2Ti_2O_7}\) has been found from its heat capacity to be consistent with that of water ice \(\mathrm{I}_h\) and Pauling’s estimate [&lt;a href=&quot;#ref-6&quot;&gt;6&lt;/a&gt;].&lt;/p&gt;

&lt;h4 id=&quot;gauge-theoretical-description-and-magnetic-monopoles&quot;&gt;Gauge theoretical description and magnetic monopoles&lt;/h4&gt;

&lt;p&gt;The fluctuations permitted by the spin-ice rule may also be understood by analogy to magnetostatics.
By identifying the spins \(\mathbf S_i\) at positions \(\mathbf r_i\) in the lattice with the local strength of an artificial magnetic field \(\mathbf B(\mathbf r_i)=\mathbf S_i\), the spin-ice rule can be summarized in a generalize Gauss’ law, \(\mathbf\nabla\cdot\mathbf B=0\) [&lt;a href=&quot;#ref-7&quot;&gt;7&lt;/a&gt;]. Hence, two magnetic “field lines” enter into each lattice tetrahedron and likewise two also exit it.
After coarse graining, this immediately implies that the correlations between magnetic fields a distance \(\mathbf r\) apart take on a dipolar form [&lt;a href=&quot;#ref-8&quot;&gt;8&lt;/a&gt;,&lt;a href=&quot;#ref-9&quot;&gt;9&lt;/a&gt;,&lt;a href=&quot;#ref-10&quot;&gt;10&lt;/a&gt;],&lt;/p&gt;

\[\left\langle\mathbf B(\mathbf 0)\otimes \mathbf B(\mathbf r)\right\rangle\sim \frac{\mathbf{r}^{\otimes 2} - \|\mathbf r\|^2/3}{\|\mathbf r\|^5},\]

&lt;p&gt;and thus decays as \(1/\|\mathbf r\|^3\) at large distances.
Power-law correlations like this are unusual away from critical regimes. They manifest themselves as sharp features called “pinch points” in the spin structure factor and have been observed in neutron scattering experiments on \(\mathrm{Ho_2Ti_2O_7}\) [&lt;a href=&quot;#ref-11&quot;&gt;11&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;Violations of the spin-ice rule lead to defects for which \(\mathbf\nabla\cdot\mathbf B\) takes on a nonvanishing value which may be interpreted as a magnetic “charge” density. Excitations above the ground state manifold thus correspond to the creation of a pair of magnetic monopoles of opposite charge at which a magnetic field line—in this context referred to as a Dirac string—originates and terminates, respectively [&lt;a href=&quot;#ref-7&quot;&gt;7&lt;/a&gt;,&lt;a href=&quot;#ref-12&quot;&gt;12&lt;/a&gt;,&lt;a href=&quot;#ref-13&quot;&gt;13&lt;/a&gt;].
Once created, the monopoles can move away from each other at no additional energy cost.
They thus constitute fractionalized excitations and the energy associated with each monopole is half that of a single spin flip [&lt;a href=&quot;#ref-14&quot;&gt;14&lt;/a&gt;].
Since the spins carry a magnetic moment, these monopoles exert a magnetostatic Coulomb interaction onto each other.
This is weak compared to the electrostatic force but its signature was nonetheless first measured in diffuse neutron scattering experiments on \(\mathrm{Dy_2Ti_2O_7}\) in 2009 [&lt;a href=&quot;#ref-15&quot;&gt;15&lt;/a&gt;].
The ensuing onslaught of experiments has focussed primarily on the dynamics of monopoles both in classical [&lt;a href=&quot;#ref-16&quot;&gt;16&lt;/a&gt;] and quantum [&lt;a href=&quot;#ref-17&quot;&gt;17&lt;/a&gt;] spin ices.
Monopoles have also been observed in artificial spin ice realized in lithographically fabricated magnetic nanodevices [&lt;a href=&quot;#ref-18&quot;&gt;18&lt;/a&gt;].&lt;/p&gt;

&lt;h4 id=&quot;classical-and-quantum-spin-liquids&quot;&gt;Classical and quantum spin liquids&lt;/h4&gt;

&lt;p&gt;Spin ices are the posterchild of a class of correlated spin states, nowadays collectively known as classical spin liquids (CSLs).
More traditionally, these have also been called correlated or cooperative paramagnets as they crucially do not exhibit long-range order, but rather strong algebraically decaying correlations.
As in the case of spin ice, these originate from fluctuations within an extensive ground-state manifold which is characterized by local constraints such as the spin-ice rule.
The constraints in turn signal the emergence of a gauge theoretical structure, complete with monopole-like fractionalized excitations.&lt;/p&gt;

&lt;p&gt;At low enough temperatures, even fluctuations within the ground-state manifold eventually slow down and the CSL may freeze out of equilibrium.
For example, in spin ice, at the very least hexagonal rings of six spins can cooperatively flip at once while remaining in the ground state.
The ever-smaller tunneling probabilities for such &lt;em&gt;zero modes&lt;/em&gt; hence cause the spins to freeze into an amorphous glassy state; in \(\mathrm{Dy_2Ti_2O_7}\) this reportedly happens below \(T_f=0.5\,\mathrm{K}\) [&lt;a href=&quot;#ref-19&quot;&gt;19&lt;/a&gt;].
Other types of CSLs may instead enter into an ordered phase below a transition temperature \(T_c\) (see “Hidden order” below for a possible mechanism).
Either way, the relevant temperatures are expected to lie significantly below the scale set by the Curie-Weiss temperature \(|\Theta_\text{CW}|\) which provides a rough estimate for the ordering temperature in unfrustrated systems.
\(\Theta_\text{CW}\) can be determined from the asymptotic high-temperature behavior of the magnetic susceptibility, \(\chi^{-1}\sim (T - \Theta_\text{CW})\).
The frustration-induced CSL behavior thus takes hold in the regime \(T_c\)&amp;lt;\(T\)&amp;lt;\(|\Theta_\text{CW}|\) and its extent is commonly quantified by the frustration parameter \(f=|\Theta_\text{CW}|/T_c\) (or \(f=|\Theta_\text{CW}|/T_f\) in case of freezing).
While \(f\sim 5\) may otherwise still occur, frustration can easily result in \(f\gg 100\) [&lt;a href=&quot;#ref-20&quot;&gt;20&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;Materials with small atomic spins might, however, display an entirely different behavior at the lowest temperatures:
quantum fluctuations due to a nonvanishing zero-point energy may allow for the formation of a quantum spin liquid (QSL) which persists down to \(T=0\), corresponding to \(f=\infty\).&lt;/p&gt;

&lt;p&gt;The energy between any two antiferromagnetically coupled spins is locally minimized by a singlet. One may naively assume that the ground state thus consists of a product of such valence bond singlets, periodically tiled over the bonds of the lattice.
Such a valence bond solid (VBS) has a vanishing total spin and is hence nonmagnetic, yet by choosing a specific dimer covering, it breaks lattice symmetries.
Anderson proposed that a system might rather form a superposition of all possible dimer coverings of spins into valence bonds on the lattice [&lt;a href=&quot;#ref-21&quot;&gt;21&lt;/a&gt;–&lt;a href=&quot;#ref-23&quot;&gt;23&lt;/a&gt;], thereby retaining the lattice symmetry.
In the language of quantum chemistry, such a state would exhibit valence bonds which constantly fluctuate amongst each other, but do so in a phase-coherent (highly entangled) way, thus coining the name resonating valence bond (RVB) state.&lt;/p&gt;

&lt;p&gt;The RVB state is the archetype of QSLs, but a superposition of dimer coverings is not the only possible microscopic realization of a QSL state and a consensus on the defining characteristics of a QSL was not reached until recently (and even that is debateable).
Quite generally, however, a “true” QSL would be expected to host fractionalized excitations [&lt;a href=&quot;#ref-20&quot;&gt;20&lt;/a&gt;,&lt;a href=&quot;#ref-24&quot;&gt;24&lt;/a&gt;].
This makes them attractive for quantum computation as it allows for the development of topological error correction codes, as exemplified by Kitaev’s toric code [&lt;a href=&quot;#ref-25&quot;&gt;25&lt;/a&gt;,&lt;a href=&quot;#ref-26&quot;&gt;26&lt;/a&gt;].
Unfortunately, as of yet, not a single QSL has been experimentally identified in an unambiguous way, despite tremendous effort over the past decade.
Extensive reviews of the state of the art of experiments into both CSLs and QSL candidates are provided in Refs. &lt;a href=&quot;#ref-24&quot;&gt;24&lt;/a&gt; and &lt;a href=&quot;#ref-27&quot;&gt;27&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;hidden-order&quot;&gt;Hidden order&lt;/h4&gt;

&lt;p&gt;The experimental identification of spin liquids, both classical and quantum, typically has to resort to a negative definition, &lt;em&gt;i.e.&lt;/em&gt; ruling out the presence of any symmetry-breaking order, in lieu of experimentally accessible genuine spin-liquid characteristics.
This is further complicated by the fact that such orders in frustrated lattice geometries may too elude common experimental probes as they do not give rise to a macroscopically observable magnetization.
For this reason, they are referred to as “hidden” orders [&lt;a href=&quot;#ref-28&quot;&gt;28&lt;/a&gt;–&lt;a href=&quot;#ref-33&quot;&gt;33&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;Indeed, even in Monte Carlo simulations of classical spin models where one has access to the full microscopic spin configuration, identifying the presence of hidden orders remains a highly nontrivial task.
This is due to their multipolar nature: in contrast to dipolar orders whose symmetry-breaking is characterized by a nonvanishing vector-like (rank-1) order parameter such as the (staggered) magnetization in the case of (anti)ferromagnetism, frustrated lattice geometries may favor orders which only break part of the full spin-rotational symmetry while staying disordered with respect to the remaining symmetry, giving rise to order parameter tensors of higher rank such as matrices (quadrupolar order) or third-rank tensors (octupolar order).
Examples can be found in spin nematic orders [&lt;a href=&quot;#ref-34&quot;&gt;34&lt;/a&gt;–&lt;a href=&quot;#ref-45&quot;&gt;45&lt;/a&gt;].
Conventional numeric probes then often suffer the same fate as their experimental counterparts and one has to resort to (weak) signatures in thermodynamic properties such as the heat capacity to pin down the presence of a phase transition.
Even then, this does not yield any insight into the nature of the tentative phase.&lt;/p&gt;

&lt;p&gt;It may seem paradoxical at first that a spin system whose ground state manifold is defined by constraints, which in and of themselves do not break any symmetries, would develop an ordered phase at low temperatures.
One mechanism to facilitate symmetry-breaking in classical systems was first described by Villain &lt;em&gt;et al.&lt;/em&gt; [&lt;a href=&quot;#ref-46&quot;&gt;46&lt;/a&gt;].
While by definition all ground states have the same energy, some of them may be entropically selected for their lower free energy.
This is the case when a certain subset of ground state configurations admits thermal fluctuations into a vast region of phase space surrounding these ground states at small energy expenditure by means of soft modes&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.
The phenomenon was coined &lt;em&gt;order-by-disorder&lt;/em&gt; [&lt;a href=&quot;#ref-8&quot;&gt;8&lt;/a&gt;] and famously accounts–among other cases [&lt;a href=&quot;#ref-47&quot;&gt;47&lt;/a&gt;]—for the selection of coplanar spin order in the Heisenberg antiferromagnet on the kagome lattice which was postulated by Chalker &lt;em&gt;et al.&lt;/em&gt; in 1992 [&lt;a href=&quot;#ref-48&quot;&gt;48&lt;/a&gt;].
However, his initial description in terms of a quadrupolar order parameter was later recognized as incomplete and rather called for an additional octupolar order parameter [&lt;a href=&quot;#ref-49&quot;&gt;49&lt;/a&gt;–&lt;a href=&quot;#ref-51&quot;&gt;51&lt;/a&gt;].&lt;/p&gt;

&lt;h4 id=&quot;premise-of-my-phd-thesis&quot;&gt;Premise of my PhD thesis&lt;/h4&gt;

&lt;p&gt;The study of frustrated magnets, particularly the quest for spin liquids—both classical and quantum—remains an active field of research in both theory and experiment.
While QSLs have proved more elusive, the occurrence and stability of CSLs, especially as compared to spin nematic phases, is far from understood.
Advances in experimental techniques over the past decade have accelerated the pace of the synthesis and charaterization of new materials to the point where it has become a matter of months, not years.
Meanwhile the process of piecing together the phase diagram of each new model remains a laborious and manual process which heavily depends on the ingenuity and intuition of individual researchers, rendering it a serious bottleneck.&lt;/p&gt;

&lt;p&gt;Devising a machine learning scheme to aid this process, inspired by the recent sprawl of activity, thus seemed like a worthwhile endeavor.
However, merely recognizing different phases in frustrated models—while useful—would not have sufficed; rather, a highly interpretable machine is in demand which allows for the reconstruction of the physical order parameter.
For this reason, we turned to kernel methods and proposed a &lt;em&gt;tensorial kernel&lt;/em&gt; (TK) function.
As the name suggests, its functional form was chosen to be capable of expressing tensorial order parameters like those characteristic of multipolar order, while not imposing any further restrictions other than locality.
Its design thus does not require the problem to be already “solved”, but covers the realm of multipolar tensor order parameters exhaustively.
When combined with a support vector machine, it is jointly referred to as TK-SVM, but the use in conjunction with kernel principal component analysis (kPCA) has also been demonstrated.&lt;/p&gt;

&lt;p&gt;In my thesis, the TK is applied to the infamous case of the aforementioned Heisenberg model on the kagome lattice as well as the XXZ model on the pyrochlore lattice which features a diverse phase diagram, including a spin nematic phase and three types of CSLs [&lt;a href=&quot;#ref-52&quot;&gt;52&lt;/a&gt;,&lt;a href=&quot;#ref-53&quot;&gt;53&lt;/a&gt;].
Indeed, the order parameter tensors of both the spin nematic phase in the case of the XXZ pyrochlore model and the &lt;em&gt;complete&lt;/em&gt; characterization of the hidden order in the kagome model have been identified by TK-SVM.&lt;/p&gt;

&lt;p&gt;Serendipitously, while the original design of the TK was aimed at expressing multipolar order, it turned out to be also capable of expressing the emergent constraints which characterize the ground-state manifold of CSLs and underpin their gauge-theoretical description.
In that regard, the method went above and beyond expectations and reconstructed the phase diagram of the XXZ pyrochlore model, including the location of the crossover regimes between different types of CSLs, with little human guidance.&lt;/p&gt;

&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;

&lt;ul id=&quot;references&quot;&gt;
	&lt;li class=&quot;unlinked&quot;&gt;
		&lt;a name=&quot;ref-1&quot;&gt;&lt;/a&gt;
		&lt;span class=&quot;pub-index&quot;&gt;[1]&lt;/span&gt;
		&lt;span&gt;
J. D. Bernal and R. H. Fowler. &lt;em&gt;A Theory of Water and Ionic Solution, with Particular Reference to Hydrogen and Hydroxyl Ions.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1063/1.1749327&quot;&gt;J. Chem. Phys. &lt;strong&gt;1&lt;/strong&gt;, 515–548&lt;/a&gt; (1933).
		&lt;/span&gt;
	&lt;/li&gt;
	&lt;li class=&quot;unlinked&quot;&gt;
		&lt;a name=&quot;ref-2&quot;&gt;&lt;/a&gt;
		&lt;span class=&quot;pub-index&quot;&gt;[2]&lt;/span&gt;
		&lt;span&gt;
Linus Pauling. &lt;em&gt;The Structure and Entropy of Ice and of Other Crystals with Some Randomness of Atomic Arrangement.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1021/ja01315a102&quot;&gt;J. Am. Chem. Soc. &lt;strong&gt;57&lt;/strong&gt;, 2680–2684&lt;/a&gt; (1935).
        &lt;/span&gt;
	&lt;/li&gt;
	&lt;li class=&quot;unlinked&quot;&gt;
		&lt;a name=&quot;ref-3&quot;&gt;&lt;/a&gt;
		&lt;span class=&quot;pub-index&quot;&gt;[3]&lt;/span&gt;
		&lt;span&gt;
M. J. Harris, S. T. Bramwell, D. F. McMorrow, T. Zeiske, and K. W. Godfrey. &lt;em&gt;Geometrical Frustration in the Ferromagnetic Pyrochlore&lt;/em&gt; Ho₂Ti₂O₇. &lt;a href=&quot;https://doi.org/10.1021/ja01315a102&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;79&lt;/strong&gt;, 2554–2557&lt;/a&gt; (1997).
        &lt;/span&gt;
	&lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-4&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[4]&lt;/span&gt;
        &lt;span&gt;
Steven T. Bramwell and Michel J. P. Gingras. &lt;em&gt;Spin Ice State in Frustrated Magnetic Pyrochlore Materials.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1126/science.1064761&quot;&gt;Science &lt;strong&gt;294&lt;/strong&gt;, 1495–1501&lt;/a&gt; (2001).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-5&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[5]&lt;/span&gt;
        &lt;span&gt;
Jason S. Gardner, Michel J. P. Gingras, and John E. Greedan. &lt;em&gt;Magnetic pyrochlore oxides.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/RevModPhys.82.53&quot;&gt;Rev. Mod. Phys. &lt;strong&gt;82&lt;/strong&gt;, 53–107&lt;/a&gt; (2010).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-6&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[6]&lt;/span&gt;
        &lt;span&gt;
A. P. Ramirez, A. Hayashi, R. J. Cava, R. Siddharthan, and B. S. Shastry. &lt;em&gt;Zero-point entropy in ‘spin ice’.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1038/20619&quot;&gt;Nature &lt;strong&gt;399&lt;/strong&gt;, 333–335&lt;/a&gt; ((1999).).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-7&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[7]&lt;/span&gt;
        &lt;span&gt;
Claudio Castelnovo, Roderich Moessner, and Shivaji L. Sondhi. &lt;em&gt;Magnetic monopoles in spin ice.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1038/nature06433&quot;&gt;Nature &lt;strong&gt;451&lt;/strong&gt;, 42–45&lt;/a&gt; (2008).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-8&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[8]&lt;/span&gt;
        &lt;span&gt;
John T. Chalker. &lt;em&gt;Geometrically Frustrated Antiferromagnets: Statistical Mechanics and Dynamics.&lt;/em&gt; In Claudine Lacroix, Philippe Mendels, and Frédéric Mila, editors, &lt;em&gt;Introduction to Frustrated Magnetism&lt;/em&gt;, chapter 1. Springer Berlin Heidelberg (2011). ISBN 978-3-642-10588-3.
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-9&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[9]&lt;/span&gt;
        &lt;span&gt;
Christopher L. Henley. &lt;em&gt;Power-law spin correlations in pyrochlore antiferromagnets.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevB.71.014424&quot;&gt;Phys. Rev. B &lt;strong&gt;71&lt;/strong&gt;, 014424&lt;/a&gt; (2005).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-10&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[10]&lt;/span&gt;
        &lt;span&gt;
Christopher L. Henley. &lt;em&gt;The “Coulomb Phase” in Frustrated Systems.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1146/annurev-conmatphys-070909-104138&quot;&gt;Annu. Rev. Condens. Matter Phys. &lt;strong&gt;1&lt;/strong&gt;, 179–210&lt;/a&gt; (2010).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-11&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[11]&lt;/span&gt;
        &lt;span&gt;
T. Fennell, P. P. Deen, A. R. Wildes, K. Schmalzl, D. Prabhakaran, A. T. Boothroyd, R. J. Aldus, D. F. McMorrow, and S. T. Bramwell. &lt;em&gt;Magnetic Coulomb Phase in the Spin Ice&lt;/em&gt; Ho₂Ti₂O₇. &lt;a href=&quot;https://doi.org/10.1126/science.1177582&quot;&gt;Science &lt;strong&gt;326&lt;/strong&gt;, 415–417&lt;/a&gt; (2009).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-12&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[12]&lt;/span&gt;
        &lt;span&gt;
Ivan A. Ryzhkin. &lt;em&gt;Magnetic relaxation in rare-earth oxide pyrochlores.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1134/1.2103216&quot;&gt;J. Exp. Theor. Phys. &lt;strong&gt;101&lt;/strong&gt;, 481–486&lt;/a&gt; (2005).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-13&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[13]&lt;/span&gt;
        &lt;span&gt;
Claudio Castelnovo, Roderich Moessner, and Shivaji L. Sondhi. &lt;em&gt;Spin Ice, Fractionalization, and Topological Order.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1146/annurev-conmatphys-020911-125058&quot;&gt;Annu. Rev. Condens. Matter Phys. &lt;strong&gt;3&lt;/strong&gt;, 35–55&lt;/a&gt; (2012).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-14&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[14]&lt;/span&gt;
        &lt;span&gt;
Ludovic D. C. Jaubert and Peter C. W. Holdsworth. &lt;em&gt;Signature of magnetic monopole and Dirac string dynamics in spin ice.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1038/nphys1227&quot;&gt;Nat. Phys. &lt;strong&gt;5&lt;/strong&gt;, 258–261&lt;/a&gt; (2009).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-15&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[15]&lt;/span&gt;
        &lt;span&gt;
D. J. P. Morris, D. A. Tennant, S. A. Grigera, B. Klemke, C. Castelnovo, R. Moessner, C. Czternasty, M. Meissner, K. C. Rule, J.-U. Hoffmann, K. Kiefer, S. Gerischer, D. Slobinsky, and R. S. Perry. &lt;em&gt;Dirac Strings and Magnetic Monopoles in the Spin Ice&lt;/em&gt; Dy₂Ti₂O₇. &lt;a href=&quot;https://doi.org/10.1126/science.1178868&quot;&gt;Science &lt;strong&gt;326&lt;/strong&gt;, 411–414&lt;/a&gt; (2009).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-16&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[16]&lt;/span&gt;
        &lt;span&gt;
Sean R. Giblin, Steven T. Bramwell, Peter C. W. Holdsworth, Dharmalingam Prabhakaran, and Ian Terry. &lt;em&gt;Creation and measurement of long-lived magnetic monopole currents in spin ice.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1038/nphys1896&quot;&gt;Nat. Phys. &lt;strong&gt;7&lt;/strong&gt;, 252–258&lt;/a&gt; (2011).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-17&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[17]&lt;/span&gt;
        &lt;span&gt;
Bruno Tomasello, Claudio Castelnovo, Roderich Moessner, and Jorge Quintanilla. &lt;em&gt;Correlated Quantum Tunneling of Monopoles in Spin Ice.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.123.067204&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;123&lt;/strong&gt;, 067204&lt;/a&gt; (2019).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-18&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[18]&lt;/span&gt;
        &lt;span&gt;
Yann Perrin, Benjamin Canals, and Nicolas Rougemaille. &lt;em&gt;Extensive degeneracy, Coulomb phase and magnetic monopoles in artificial square ice.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1038/nature20155&quot;&gt;Nature &lt;strong&gt;540&lt;/strong&gt;, 410–413&lt;/a&gt; (2016).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-19&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[19]&lt;/span&gt;
        &lt;span&gt;
H. Fukazawa, R. G. Melko, R. Higashinaka, Y. Maeno, and M. J. P. Gingras. &lt;em&gt;Magnetic anisotropy of the spin-ice compound&lt;/em&gt; Dy₂Ti₂O₇. &lt;a href=&quot;https://doi.org/10.1103/PhysRevB.65.054410&quot;&gt;Phys. Rev. B &lt;strong&gt;65&lt;/strong&gt;, 054410&lt;/a&gt; (2002).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-20&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[20]&lt;/span&gt;
        &lt;span&gt;
Leon Balents. &lt;em&gt;Spin liquids in frustrated magnets.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1038/nature08917&quot;&gt;Nature &lt;strong&gt;464&lt;/strong&gt;, 199–208&lt;/a&gt; (2010).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-21&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[21]&lt;/span&gt;
        &lt;span&gt;
G. Baskaran, Z. Zou, and P. W. Anderson. &lt;em&gt;The resonating valence bond state and high-T&lt;sub&gt;c&lt;/sub&gt; superconductivity — A mean field theory.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1016/0038-1098(87)90642-9&quot;&gt;Solid State Commun. &lt;strong&gt;63&lt;/strong&gt;, 973–976&lt;/a&gt; (1987).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-22&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[22]&lt;/span&gt;
        &lt;span&gt;
P. W. Anderson, G. Baskaran, Z. Zou, and T. Hsu. &lt;em&gt;Resonating-valence-bond theory of phase transitions and superconductivity in&lt;/em&gt; La₂CuO₄&lt;em&gt;-based compounds.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.58.2790&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;58&lt;/strong&gt;, 2790–2793&lt;/a&gt; (1987).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-23&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[23]&lt;/span&gt;
        &lt;span&gt;
G. Baskaran and P. W. Anderson. &lt;em&gt;Gauge theory of high-temperature superconductors and strongly correlated Fermi systems.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevB.37.580&quot;&gt;Phys. Rev. B &lt;strong&gt;37&lt;/strong&gt;, 580–583&lt;/a&gt; (1988).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-24&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[24]&lt;/span&gt;
        &lt;span&gt;
Lucile Savary and Leon Balents. &lt;em&gt;Quantum spin liquids: a review.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1088/0034-4885/80/1/016502&quot;&gt;Rep. Prog. Phys. &lt;strong&gt;80&lt;/strong&gt;, 016502&lt;/a&gt; (2017).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-25&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[25]&lt;/span&gt;
        &lt;span&gt;
Alexei Yu. Kitaev. &lt;em&gt;Fault-tolerant quantum computation by anyons.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1016/S0003-4916(02)00018-0&quot;&gt;Ann. Phys. (N. Y.) &lt;strong&gt;303&lt;/strong&gt;, 2–30&lt;/a&gt; (2003).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-26&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[26]&lt;/span&gt;
        &lt;span&gt;
Alexei Kitaev and Chris Laumann. &lt;em&gt;Topological quantum phases and quantum computation.&lt;/em&gt; In Jesper Jacobsen, Stephane Ouvry, Vincent Pasquier, Didina Serban, and Leticia Cugliandolo, editors, &lt;em&gt;Exact Methods in Low-dimensional Statistical Physics and Quantum Computing&lt;/em&gt;, volume 89 of &lt;em&gt;Lecture Notes of the Les Houches Summer School&lt;/em&gt;, chapter 4. Oxford University Press, Oxford, U.K. (2008), &lt;a href=&quot;https://arXiv.org/abs/0904.2771&quot;&gt;arXiv:0904.2771&lt;/a&gt;.
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-27&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[27]&lt;/span&gt;
        &lt;span&gt;
Yi Zhou, Kazushi Kanoda, and Tai-Kai Ng. &lt;em&gt;Quantum spin liquid states.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/RevModPhys.89.025003&quot;&gt;Rev. Mod. Phys. &lt;strong&gt;89&lt;/strong&gt;, 025003&lt;/a&gt; (2017).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-28&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[28]&lt;/span&gt;
        &lt;span&gt;
Nic Shannon, Tsutomu Momoi, and Philippe Sindzingre. &lt;em&gt;Nematic Order in Square Lattice Frustrated Ferromagnets.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.96.027213&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;96&lt;/strong&gt;, 027213&lt;/a&gt; (2006).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-29&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[29]&lt;/span&gt;
        &lt;span&gt;
John A. Mydosh and Peter M. Oppeneer. Colloquium: &lt;em&gt;Hidden order, superconductivity, and magnetism: The unsolved case of&lt;/em&gt; URu₂Si₂. &lt;a href=&quot;https://doi.org/10.1103/RevModPhys.83.1301&quot;&gt;Rev. Mod. Phys. &lt;strong&gt;83&lt;/strong&gt;, 1301–1322&lt;/a&gt; (2011).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-30&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[30]&lt;/span&gt;
        &lt;span&gt;
Joseph A. M. Paddison, Henrik Jacobsen, Oleg A. Petrenko, Maria Teresa Fernández-Díaz, Pascale P. Deen, and Andrew L. Goodwin. &lt;em&gt;Hidden order in spin-liquid&lt;/em&gt; Gd₃Ga₅O₁₂. &lt;a href=&quot;https://doi.org/10.1126/science.aaa5326&quot;&gt;Science &lt;strong&gt;350&lt;/strong&gt;, 179–181&lt;/a&gt; (2015).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-31&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[31]&lt;/span&gt;
        &lt;span&gt;
Yao-Dong Li, Xiaoqun Wang, and Gang Chen. &lt;em&gt;Hidden multipolar orders of dipole-octupole doublets on a triangular lattice.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevB.94.201114&quot;&gt;Phys. Rev. B &lt;strong&gt;94&lt;/strong&gt;, 201114&lt;/a&gt; (2016).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-32&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[32]&lt;/span&gt;
        &lt;span&gt;
H. Takatsu, S. Onoda, S. Kittaka, A. Kasahara, Y. Kono, T. Sakakibara, Y. Kato, B. Fåk, J. Ollivier, J. W. Lynn, T. Taniguchi, M. Wakita, and H. Kadowaki. &lt;em&gt;Quadrupole Order in the Frustrated Pyrochlore&lt;/em&gt; Tb&lt;sub&gt;2+x&lt;/sub&gt;Ti&lt;sub&gt;2-x&lt;/sub&gt;O&lt;sub&gt;7+y&lt;/sub&gt;. &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.116.217201&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;116&lt;/strong&gt;, 217201&lt;/a&gt; (2016).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-33&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[33]&lt;/span&gt;
        &lt;span&gt;
Qiang Luo, Shijie Hu, Bin Xi, Jize Zhao, and Xiaoqun Wang. &lt;em&gt;Ground-state phase diagram
of an anisotropic spin-½ model on the triangular lattice.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevB.95.165110&quot;&gt;Phys. Rev. B &lt;strong&gt;95&lt;/strong&gt;, 165110&lt;/a&gt; (2017).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-34&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[34]&lt;/span&gt;
        &lt;span&gt;
A. F. Andreev and I. A. Grishchuk. &lt;em&gt;Spin Nematics.&lt;/em&gt; J. Exp. Theor. Phys. 87, 467–475 (1984).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-35&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[35]&lt;/span&gt;
        &lt;span&gt;
Andrey V. Chubukov. &lt;em&gt;Fluctuations in spin nematics.&lt;/em&gt; J. Phys.: Condens. Matter 2, 1593 (1990).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-36&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[36]&lt;/span&gt;
        &lt;span&gt;
Tsutomu Momoi, Philippe Sindzingre, and Nic Shannon. &lt;em&gt;Octupolar Order in the Multiple Spin Exchange Model on a Triangular Lattice.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.97.257204&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;97&lt;/strong&gt;, 257204&lt;/a&gt; (2006).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-37&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[37]&lt;/span&gt;
        &lt;span&gt;
Tsutomu Momoi, Philippe Sindzingre, and Kenn Kubo. &lt;em&gt;Spin Nematic Order in Multiple-Spin Exchange Models on the Triangular Lattice.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.108.057206&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;108&lt;/strong&gt;, 057206&lt;/a&gt; (2012).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-38&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[38]&lt;/span&gt;
        &lt;span&gt;
Roderich Moessner and John T. Chalker. &lt;em&gt;Low-temperature properties of classical geometrically frustrated antiferromagnets.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevB.58.12049&quot;&gt;Phys. Rev. B &lt;strong&gt;58&lt;/strong&gt;, 12049–12062&lt;/a&gt; (1998).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-39&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[39]&lt;/span&gt;
        &lt;span&gt;
Andreas Läuchli, Frédéric Mila, and Karlo Penc. &lt;em&gt;Quadrupolar Phases of the S=1 Bilinear-Biquadratic Heisenberg Model on the Triangular Lattice.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.97.087205&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;97&lt;/strong&gt;, 087205&lt;/a&gt; (2006).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-40&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[40]&lt;/span&gt;
        &lt;span&gt;
Congjun Wu. &lt;em&gt;Orbital Ordering and Frustration of p-Band Mott Insulators.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.100.200406&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;100&lt;/strong&gt;, 200406&lt;/a&gt; (2008).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-41&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[41]&lt;/span&gt;
        &lt;span&gt;
J. Yamaura, K. Ohgushi, H. Ohsumi, T. Hasegawa, I. Yamauchi, K. Sugimoto, S. Takeshita, A. Tokuda, M. Takata, M. Udagawa, M. Takigawa, H. Harima, T. Arima, and Z. Hiroi. &lt;em&gt;Tetrahedral Magnetic Order and the Metal-Insulator Transition in the Pyrochlore Lattice of&lt;/em&gt; Cd₂Os₂O₇. &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.108.247205&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;108&lt;/strong&gt;, 247205&lt;/a&gt; (2012).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-42&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[42]&lt;/span&gt;
        &lt;span&gt;
M. Mourigal, M. Enderle, B. Fåk, R. K. Kremer, J. M. Law, A. Schneidewind, A. Hiess, and A. Prokofiev. &lt;em&gt;Evidence of a Bond-Nematic Phase in&lt;/em&gt; LiCuVO₄. &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.109.027203&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;109&lt;/strong&gt;, 027203&lt;/a&gt; (2012).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-43&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[43]&lt;/span&gt;
        &lt;span&gt;
O. Janson, J. Richter, P. Sindzingre, and H. Rosner. &lt;em&gt;Coupled frustrated quantum spin-½ chains with orbital order in volborthite&lt;/em&gt; Cu₃V₂O₇(OH)₂ · 2H₂O. &lt;a href=&quot;https://doi.org/10.1103/PhysRevB.82.104434&quot;&gt;Phys. Rev. B &lt;strong&gt;82&lt;/strong&gt;, 104434&lt;/a&gt; (2010).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-44&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[44]&lt;/span&gt;
        &lt;span&gt;
R. Wawrzyńczak, Y. Tanaka, M. Yoshida, Y. Okamoto, P. Manuel, N. Casati, Z. Hiroi, M. Takigawa, and G. J. Nilsen. &lt;em&gt;Classical Spin Nematic Transition in&lt;/em&gt; LiGa&lt;sub&gt;0.95&lt;/sub&gt;In&lt;sub&gt;0.05&lt;/sub&gt;Cr&lt;sub&gt;4&lt;/sub&gt;O&lt;sub&gt;8&lt;/sub&gt;. &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.119.087201&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;119&lt;/strong&gt;, 087201&lt;/a&gt; (2017).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-45&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[45]&lt;/span&gt;
        &lt;span&gt;
A. Orlova, E. L. Green, J. M. Law, D. I. Gorbunov, G. Chanda, S. Krämer, M. Horvatić, R. K. Kremer, J. Wosnitza, and G. L. J. A. Rikken. &lt;em&gt;Nuclear Magnetic Resonance Signature of the Spin-Nematic Phase in&lt;/em&gt; LiCuVO₄ &lt;em&gt;at High Magnetic Fields.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.118.247201&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;118&lt;/strong&gt;, 247201&lt;/a&gt; (2017).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-46&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[46]&lt;/span&gt;
        &lt;span&gt;
Jacques Villain, R. Bidaux, J.-P. Carton, and R. Conte. &lt;em&gt;Order as an effect of disorder.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1051/jphys:0198000410110126300&quot;&gt;J. Phys. France &lt;strong&gt;41&lt;/strong&gt;, 1263–1272&lt;/a&gt; (1980).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-47&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[47]&lt;/span&gt;
        &lt;span&gt;
Doron Bergman, Jason Alicea, Emanuel Gull, Simon Trebst, and Leon Balents. &lt;em&gt;Order-by-disorder and spiral spin-liquid in frustrated diamond-lattice antiferromagnets.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1038/nphys622&quot;&gt;Nat. Phys.
&lt;strong&gt;3&lt;/strong&gt;, 487–491&lt;/a&gt; (2007).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-48&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[48]&lt;/span&gt;
        &lt;span&gt;
John T. Chalker, Peter C. W. Holdsworth, and E. F. Shender. &lt;em&gt;Hidden order in a frustrated system: Properties of the Heisenberg Kagomé antiferromagnet.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.68.855&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;68&lt;/strong&gt;, 855–858&lt;/a&gt; (1992).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-49&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[49]&lt;/span&gt;
        &lt;span&gt;
I. Ritchey, P. Chandra, and P. Coleman. &lt;em&gt;Spin folding in the two-dimensional Heisenberg kagomé antiferromagnet.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevB.47.15342&quot;&gt;Phys. Rev. B &lt;strong&gt;47&lt;/strong&gt;, 15342–15345&lt;/a&gt; (1993).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-50&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[50]&lt;/span&gt;
        &lt;span&gt;
Michael E. Zhitomirsky. &lt;em&gt;Field-Induced Transitions in a Kagomé Antiferromagnet.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.88.057204&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;88&lt;/strong&gt;, 057204&lt;/a&gt; (2002).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-51&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[51]&lt;/span&gt;
        &lt;span&gt;
Michael E. Zhitomirsky. &lt;em&gt;Octupolar ordering of classical kagome antiferromagnets in two and three dimensions.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevB.78.094423&quot;&gt;Phys. Rev. B &lt;strong&gt;78&lt;/strong&gt;, 094423&lt;/a&gt; (2008).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-52&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[52]&lt;/span&gt;
        &lt;span&gt;
Mathieu Taillefumier, Owen Benton, Han Yan, L. D. C. Jaubert, and Nic Shannon. &lt;em&gt;Competing Spin Liquids and Hidden Spin-Nematic Order in Spin Ice with Frustrated Transverse Exchange.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevX.7.041057&quot;&gt;Phys. Rev. X &lt;strong&gt;7&lt;/strong&gt;, 041057&lt;/a&gt; (2017).
        &lt;/span&gt;
    &lt;/li&gt;
    &lt;li class=&quot;unlinked&quot;&gt;
        &lt;a name=&quot;ref-53&quot;&gt;&lt;/a&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[53]&lt;/span&gt;
        &lt;span&gt;
Owen Benton, Ludovic D. C. Jaubert, Rajiv R. P. Singh, Jaan Oitmaa, and Nic Shannon. &lt;em&gt;Quantum Spin Ice with Frustrated Transverse Exchange: From a π-Flux Phase to a Nematic
Quantum Spin Liquid.&lt;/em&gt; &lt;a href=&quot;https://doi.org/10.1103/PhysRevLett.121.067201&quot;&gt;Phys. Rev. Lett. &lt;strong&gt;121&lt;/strong&gt;, 067201&lt;/a&gt; (2018).
        &lt;/span&gt;
    &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;The term “soft mode” usually refers to any kind of gapless mode, including those with linearly vanishing dispersions; here, modes need to be even “softer”, with at-most quadratic dispersion, to fluctuate appreciably down to the low temperatures required for order to emerge. &lt;a href=&quot;#fnref:1&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>Tue, 03 Sep 2019 21:58:09 +0000</pubDate>
        <link>https://greitemann.dev/2019/09/03/frustrated-magnetism-thesis-motivation/</link>
        <guid isPermaLink="true">https://greitemann.dev/2019/09/03/frustrated-magnetism-thesis-motivation/</guid>
        
        <category>physics</category>
        
        <category>thesis</category>
        
        <category>machine-learning</category>
        
        
      </item>
    
      <item>
        <title>Thesis handed in 🥳</title>
        <description>&lt;p&gt;Over the past few month, I have been busy finishing &lt;a href=&quot;/publications/1907.12322/&quot;&gt;yet another SVM-related paper&lt;/a&gt;
(more on that in an upcoming post) but also writing my PhD thesis which I am happy to have handed in last week.&lt;/p&gt;

&lt;p&gt;As you do, I tried to shove as much of my research into it as possible and the final couple of weeks in particular have been quite stressful. It is thus with great relieve that this chapter of my career has (almost – pending the defense) come to a close.&lt;/p&gt;

&lt;p&gt;At the same time, August is the last month of my working at LMU and also marks the end of my full-time scientific career as I have decided not to seek out any post-doc positions. Rather, I’m now on the look out for attractive jobs in industry, as a software engineer or the like. While I am somewhat saddened to abandon physics in general, and our work on frustrated magnetism in particular, I’m all the more excited to face the new challenges which lay ahead.&lt;/p&gt;

&lt;p&gt;There’s still a bit of “legacy work” to be done on the TK-SVM project. For one, I will update the &lt;a href=&quot;https://gitlab.physik.uni-muenchen.de/LDAP_ls-schollwoeck/svm-order-params&quot;&gt;published code&lt;/a&gt; to a new version containing additional tools developed during the analysis of the XXZ pyrochlore model for the recent preprint. &lt;del&gt;I will also put out another blog post or two on a WebAssembly-based interactive browser version of the graph analysis.&lt;/del&gt;&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
Finally, I’m going to publish some &lt;a href=&quot;2019/09/03/frustrated-magnetism-thesis-motivation/&quot;&gt;excerpts from the introduction&lt;/a&gt; of my thesis on this blog. &lt;del&gt;The full thesis will also eventually be published somewhere on here after the defense.&lt;/del&gt; &lt;em&gt;Update: the thesis is now &lt;a href=&quot;https://nbn-resolving.org/urn:nbn:de:bvb:19-250579&quot;&gt;published&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I might still be involved with some of the future research revolving around our TK-SVM method down the line in a less active capacity in my spare time. For now, I look forward to shifting my attention away from that and to gather experience in both new tech and as pertaining to the non-academic workplace.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;em&gt;Update:&lt;/em&gt; I’ve not yet come around to do so and I’m not sure I will any time soon. The interactive browser version is however available &lt;a href=&quot;https://jgreitemann.github.io/messing-with-wasm/graph-analysis/&quot;&gt;here&lt;/a&gt; without further information. It is hopefully pretty self-explanatory when compared to the corresponding figures in &lt;a href=&quot;/publications/1907.12322/&quot;&gt;the paper&lt;/a&gt;. &lt;a href=&quot;#fnref:1&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>Fri, 30 Aug 2019 13:43:40 +0000</pubDate>
        <link>https://greitemann.dev/2019/08/30/thesis-handed-in/</link>
        <guid isPermaLink="true">https://greitemann.dev/2019/08/30/thesis-handed-in/</guid>
        
        <category>meta</category>
        
        <category>physics</category>
        
        <category>thesis</category>
        
        
      </item>
    
      <item>
        <title>Two papers published in PRB</title>
        <description>&lt;p&gt;It’s my pleasure to annouce that as of last week, both of the papers we worked on last year have been published in Phys. Rev. B:&lt;/p&gt;

&lt;ul id=&quot;references&quot;&gt;



&lt;li&gt;
    &lt;aside&gt;

        &lt;a class=&quot;ref-link&quot; href=&quot;https://doi.org/10.1103/PhysRevB.99.060404&quot;&gt;
            DOI
        &lt;/a&gt;

        &lt;a class=&quot;ref-link&quot; href=&quot;https://arxiv.org/abs/1804.08557&quot;&gt;
            &lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 16 16&quot; version=&quot;1.1&quot; id=&quot;svg4&quot;&gt;
&lt;g id=&quot;g4553&quot; transform=&quot;translate(0.4070129,-8)&quot; /&gt;
&lt;g id=&quot;g4564&quot; transform=&quot;translate(0.030689,-8)&quot; /&gt;
&lt;g id=&quot;g4580&quot; transform=&quot;translate(-0.0505842,-8.185246)&quot; /&gt;
&lt;g id=&quot;g1255&quot; transform=&quot;matrix(0.6778966,0,0,0.6778966,-0.17663454,-0.16543929)&quot; style=&quot;fill-opacity:1&quot;&gt;
&lt;path d=&quot;M 5.9960938,2.8632812 C 5.8337258,2.853933 5.6686568,2.8678983 5.5058594,2.9101562 4.9004518,3.0673042 4.4792607,3.5815323 4.3710938,4.1894531 4.0542815,4.2235209 3.7326401,4.2839172 3.4785156,4.5078125 2.8480133,5.063314 2.7583177,6.0266468 3.2773438,6.6875 3.6893307,7.2120649 4.359747,7.302234 4.9707031,7.1210938 L 6.71875,8.8691406 C 6.1610731,9.8035386 5.7539064,10.835185 5.7539062,12 c 2e-7,1.16461 0.4073488,2.194618 0.9648438,3.128906 l -1.75,1.75 c -0.6105546,-0.180315 -1.2797814,-0.09246 -1.6914062,0.431641 -0.5190265,0.660853 -0.4312835,1.62614 0.1992187,2.181641 0.2542199,0.22398 0.577594,0.284349 0.8945313,0.318359 0.1082498,0.607803 0.5294435,1.120218 1.1347656,1.277344 0.651188,0.169031 1.3415012,-0.09139 1.71875,-0.648438 0.2875944,-0.424665 0.2756832,-0.93605 0.1113281,-1.404297 L 8.875,17.322266 c 0.0087,-0.0069 0.017168,-0.01404 0.025391,-0.02148 0.9272955,0.546 1.948034,0.94336 3.099609,0.94336 1.15196,0 2.172106,-0.397021 3.099609,-0.94336 0.0082,0.0074 0.01669,0.0146 0.02539,0.02148 l 1.537109,1.71289 c -0.164217,0.46817 -0.176202,0.979727 0.111329,1.404297 0.377248,0.557051 1.069515,0.817469 1.720703,0.648438 0.606185,-0.15735 1.029306,-0.670315 1.136718,-1.279297 0.315417,-0.03471 0.637566,-0.09345 0.890625,-0.316406 0.630503,-0.555501 0.720199,-1.520788 0.201172,-2.181641 -0.412044,-0.524639 -1.082339,-0.612912 -1.693359,-0.431641 L 17.28125,15.130859 C 17.83926,14.196261 18.244141,13.165192 18.244141,12 c 0,-1.164815 -0.405214,-2.1964614 -0.962891,-3.1308594 l 1.748047,-1.75 C 19.640361,7.3005042 20.310571,7.2121896 20.722656,6.6875 21.241682,6.0266467 21.151987,5.0633139 20.521484,4.5078125 20.268425,4.2848559 19.946276,4.2261167 19.630859,4.1914062 19.523528,3.5823094 19.10041,3.0675278 18.494141,2.9101562 c -0.65119,-0.1690317 -1.343455,0.09139 -1.720703,0.6484376 -0.287826,0.425005 -0.27422,0.9377278 -0.109376,1.40625 L 15.103516,6.7011719 C 14.175173,6.1534664 13.153516,5.7539063 12,5.7539062 c -1.151575,0 -2.1723139,0.3993125 -3.0996094,0.9453126 -0.010034,-0.00954 -0.020459,-0.018666 -0.03125,-0.027344 L 7.3359375,4.9628906 C 7.4998868,4.4948709 7.5139671,3.9829784 7.2265625,3.5585938 6.9436264,3.1408072 6.4831975,2.8913259 5.9960938,2.8632812 Z M 10,8.46875 c 0.283496,0 0.458079,0.183322 0.544922,0.3125 0.08685,0.129178 0.132635,0.2565282 0.171875,0.3945312 0.07848,0.2760081 0.115234,0.6015027 0.115234,0.9628908 0,0.361387 -0.03675,0.686884 -0.115234,0.96289 -0.03924,0.138005 -0.08503,0.265354 -0.171875,0.394532 -0.08684,0.129177 -0.261426,0.3125 -0.544922,0.3125 -0.2834963,0 -0.4580789,-0.183323 -0.5449219,-0.3125 -0.086843,-0.129178 -0.132634,-0.256527 -0.171875,-0.394532 -0.078482,-0.276006 -0.1152343,-0.601503 -0.1152343,-0.96289 -1e-7,-0.3613881 0.036752,-0.6868828 0.1152343,-0.9628908 C 9.3224442,9.0377782 9.3682351,8.910428 9.4550781,8.78125 9.5419209,8.652072 9.7165037,8.46875 10,8.46875 Z m 4,0 c 0.283496,0 0.458079,0.183322 0.544922,0.3125 0.08685,0.129178 0.132635,0.2565282 0.171875,0.3945312 0.07848,0.2760081 0.115234,0.6015027 0.115234,0.9628908 0,0.361387 -0.03675,0.686884 -0.115234,0.96289 -0.03924,0.138005 -0.08503,0.265354 -0.171875,0.394532 -0.08684,0.129177 -0.261426,0.3125 -0.544922,0.3125 -0.283496,0 -0.458082,-0.183323 -0.544922,-0.3125 -0.08685,-0.129178 -0.132635,-0.256527 -0.171875,-0.394532 -0.07848,-0.276006 -0.115234,-0.601503 -0.115234,-0.96289 0,-0.3613881 0.03675,-0.6868828 0.115234,-0.9628908 C 13.322444,9.0377782 13.368238,8.910428 13.455078,8.78125 13.541921,8.652072 13.716504,8.46875 14,8.46875 Z M 9.1835938,12.791016 9.9101562,13.234375 9.6875,13.597656 c 0,0 -0.024933,0.02065 -0.025391,0.02149 0.2004502,0.203097 0.524243,0.590787 1.298829,0.892578 0.92065,0.3587 2.069989,0.354774 3.382812,-0.888672 -7.2e-4,-0.0013 -0.0332,-0.02539 -0.0332,-0.02539 l -0.220703,-0.363281 0.724609,-0.443359 0.222656,0.361328 c 0,0 0.239519,0.323561 0.466797,0.394531 l 0.40625,0.126953 -0.253906,0.8125 L 15.25,14.359375 c -0.157792,-0.04928 -0.169891,-0.06264 -0.287109,-0.142578 -1.557475,1.527301 -3.14748,1.541039 -4.310547,1.087891 -1.0131016,-0.39472 -1.4737332,-0.853347 -1.6660159,-1.058594 -0.1214069,0.08534 -0.071663,0.06125 -0.2382812,0.113281 l -0.4042969,0.126953 -0.2539062,-0.8125 0.40625,-0.126953 c 0.2216053,-0.0692 0.4435501,-0.369376 0.4550781,-0.384766 l 0.011719,-0.0098 z&quot; transform=&quot;translate(0.0621696,0.04623419)&quot; id=&quot;path1249&quot; inkscape:connector-curvature=&quot;0&quot; /&gt;
&lt;/g&gt;
&lt;/svg&gt;

            1804.08557
        &lt;/a&gt;
    &lt;/aside&gt;
    &lt;a href=&quot;/publications/1804.08557/&quot;&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[4]&lt;/span&gt;
        &lt;span&gt;
            Phys. Rev. B 99, 060404(R)

            (2019)

        &lt;/span&gt;

        &lt;div class=&quot;pub-byline&quot;&gt;

            JG, Ke Liu, and Lode Pollet:


            &lt;em&gt;
                Probing hidden spin order with interpretable machine learning.
            &lt;/em&gt;

        &lt;/div&gt;



    &lt;/a&gt;
&lt;/li&gt;



&lt;li&gt;
    &lt;aside&gt;

        &lt;a class=&quot;ref-link&quot; href=&quot;https://doi.org/10.1103/PhysRevB.99.104410&quot;&gt;
            DOI
        &lt;/a&gt;

        &lt;a class=&quot;ref-link&quot; href=&quot;https://arxiv.org/abs/1810.05538&quot;&gt;
            &lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 16 16&quot; version=&quot;1.1&quot; id=&quot;svg4&quot;&gt;
&lt;g id=&quot;g4553&quot; transform=&quot;translate(0.4070129,-8)&quot; /&gt;
&lt;g id=&quot;g4564&quot; transform=&quot;translate(0.030689,-8)&quot; /&gt;
&lt;g id=&quot;g4580&quot; transform=&quot;translate(-0.0505842,-8.185246)&quot; /&gt;
&lt;g id=&quot;g1255&quot; transform=&quot;matrix(0.6778966,0,0,0.6778966,-0.17663454,-0.16543929)&quot; style=&quot;fill-opacity:1&quot;&gt;
&lt;path d=&quot;M 5.9960938,2.8632812 C 5.8337258,2.853933 5.6686568,2.8678983 5.5058594,2.9101562 4.9004518,3.0673042 4.4792607,3.5815323 4.3710938,4.1894531 4.0542815,4.2235209 3.7326401,4.2839172 3.4785156,4.5078125 2.8480133,5.063314 2.7583177,6.0266468 3.2773438,6.6875 3.6893307,7.2120649 4.359747,7.302234 4.9707031,7.1210938 L 6.71875,8.8691406 C 6.1610731,9.8035386 5.7539064,10.835185 5.7539062,12 c 2e-7,1.16461 0.4073488,2.194618 0.9648438,3.128906 l -1.75,1.75 c -0.6105546,-0.180315 -1.2797814,-0.09246 -1.6914062,0.431641 -0.5190265,0.660853 -0.4312835,1.62614 0.1992187,2.181641 0.2542199,0.22398 0.577594,0.284349 0.8945313,0.318359 0.1082498,0.607803 0.5294435,1.120218 1.1347656,1.277344 0.651188,0.169031 1.3415012,-0.09139 1.71875,-0.648438 0.2875944,-0.424665 0.2756832,-0.93605 0.1113281,-1.404297 L 8.875,17.322266 c 0.0087,-0.0069 0.017168,-0.01404 0.025391,-0.02148 0.9272955,0.546 1.948034,0.94336 3.099609,0.94336 1.15196,0 2.172106,-0.397021 3.099609,-0.94336 0.0082,0.0074 0.01669,0.0146 0.02539,0.02148 l 1.537109,1.71289 c -0.164217,0.46817 -0.176202,0.979727 0.111329,1.404297 0.377248,0.557051 1.069515,0.817469 1.720703,0.648438 0.606185,-0.15735 1.029306,-0.670315 1.136718,-1.279297 0.315417,-0.03471 0.637566,-0.09345 0.890625,-0.316406 0.630503,-0.555501 0.720199,-1.520788 0.201172,-2.181641 -0.412044,-0.524639 -1.082339,-0.612912 -1.693359,-0.431641 L 17.28125,15.130859 C 17.83926,14.196261 18.244141,13.165192 18.244141,12 c 0,-1.164815 -0.405214,-2.1964614 -0.962891,-3.1308594 l 1.748047,-1.75 C 19.640361,7.3005042 20.310571,7.2121896 20.722656,6.6875 21.241682,6.0266467 21.151987,5.0633139 20.521484,4.5078125 20.268425,4.2848559 19.946276,4.2261167 19.630859,4.1914062 19.523528,3.5823094 19.10041,3.0675278 18.494141,2.9101562 c -0.65119,-0.1690317 -1.343455,0.09139 -1.720703,0.6484376 -0.287826,0.425005 -0.27422,0.9377278 -0.109376,1.40625 L 15.103516,6.7011719 C 14.175173,6.1534664 13.153516,5.7539063 12,5.7539062 c -1.151575,0 -2.1723139,0.3993125 -3.0996094,0.9453126 -0.010034,-0.00954 -0.020459,-0.018666 -0.03125,-0.027344 L 7.3359375,4.9628906 C 7.4998868,4.4948709 7.5139671,3.9829784 7.2265625,3.5585938 6.9436264,3.1408072 6.4831975,2.8913259 5.9960938,2.8632812 Z M 10,8.46875 c 0.283496,0 0.458079,0.183322 0.544922,0.3125 0.08685,0.129178 0.132635,0.2565282 0.171875,0.3945312 0.07848,0.2760081 0.115234,0.6015027 0.115234,0.9628908 0,0.361387 -0.03675,0.686884 -0.115234,0.96289 -0.03924,0.138005 -0.08503,0.265354 -0.171875,0.394532 -0.08684,0.129177 -0.261426,0.3125 -0.544922,0.3125 -0.2834963,0 -0.4580789,-0.183323 -0.5449219,-0.3125 -0.086843,-0.129178 -0.132634,-0.256527 -0.171875,-0.394532 -0.078482,-0.276006 -0.1152343,-0.601503 -0.1152343,-0.96289 -1e-7,-0.3613881 0.036752,-0.6868828 0.1152343,-0.9628908 C 9.3224442,9.0377782 9.3682351,8.910428 9.4550781,8.78125 9.5419209,8.652072 9.7165037,8.46875 10,8.46875 Z m 4,0 c 0.283496,0 0.458079,0.183322 0.544922,0.3125 0.08685,0.129178 0.132635,0.2565282 0.171875,0.3945312 0.07848,0.2760081 0.115234,0.6015027 0.115234,0.9628908 0,0.361387 -0.03675,0.686884 -0.115234,0.96289 -0.03924,0.138005 -0.08503,0.265354 -0.171875,0.394532 -0.08684,0.129177 -0.261426,0.3125 -0.544922,0.3125 -0.283496,0 -0.458082,-0.183323 -0.544922,-0.3125 -0.08685,-0.129178 -0.132635,-0.256527 -0.171875,-0.394532 -0.07848,-0.276006 -0.115234,-0.601503 -0.115234,-0.96289 0,-0.3613881 0.03675,-0.6868828 0.115234,-0.9628908 C 13.322444,9.0377782 13.368238,8.910428 13.455078,8.78125 13.541921,8.652072 13.716504,8.46875 14,8.46875 Z M 9.1835938,12.791016 9.9101562,13.234375 9.6875,13.597656 c 0,0 -0.024933,0.02065 -0.025391,0.02149 0.2004502,0.203097 0.524243,0.590787 1.298829,0.892578 0.92065,0.3587 2.069989,0.354774 3.382812,-0.888672 -7.2e-4,-0.0013 -0.0332,-0.02539 -0.0332,-0.02539 l -0.220703,-0.363281 0.724609,-0.443359 0.222656,0.361328 c 0,0 0.239519,0.323561 0.466797,0.394531 l 0.40625,0.126953 -0.253906,0.8125 L 15.25,14.359375 c -0.157792,-0.04928 -0.169891,-0.06264 -0.287109,-0.142578 -1.557475,1.527301 -3.14748,1.541039 -4.310547,1.087891 -1.0131016,-0.39472 -1.4737332,-0.853347 -1.6660159,-1.058594 -0.1214069,0.08534 -0.071663,0.06125 -0.2382812,0.113281 l -0.4042969,0.126953 -0.2539062,-0.8125 0.40625,-0.126953 c 0.2216053,-0.0692 0.4435501,-0.369376 0.4550781,-0.384766 l 0.011719,-0.0098 z&quot; transform=&quot;translate(0.0621696,0.04623419)&quot; id=&quot;path1249&quot; inkscape:connector-curvature=&quot;0&quot; /&gt;
&lt;/g&gt;
&lt;/svg&gt;

            1810.05538
        &lt;/a&gt;
    &lt;/aside&gt;
    &lt;a href=&quot;/publications/1810.05538/&quot;&gt;
        &lt;span class=&quot;pub-index&quot;&gt;[5]&lt;/span&gt;
        &lt;span&gt;
            Phys. Rev. B 99, 104410

            (2019)

        &lt;/span&gt;

        &lt;div class=&quot;pub-byline&quot;&gt;

            Ke Liu, JG, and Lode Pollet:


            &lt;em&gt;
                Learning multiple order parameters with interpretable machines.
            &lt;/em&gt;

        &lt;/div&gt;



    &lt;/a&gt;
&lt;/li&gt;


&lt;/ul&gt;

&lt;p&gt;The &lt;em&gt;Rapid Communication&lt;/em&gt; was even selected as an Editors’ Suggestion, giving it a few days of exposure on PRB’s home page:&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;/assets/img/prb-screenshot.png&quot; alt=&quot;Screenshot of the PRB home page; Feb 11, 2019&quot; width=&quot;75%&quot; class=&quot;shadow&quot; /&gt;

&lt;figcaption&gt;&lt;p&gt;Screenshot of the PRB home page; Feb 11, 2019&lt;/p&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;Along with the second paper which investigates the use of multiclassification, we have made the corresponding source codes openly available under the terms of the &lt;em&gt;GNU General Public License version 3&lt;/em&gt;. An extensive &lt;a href=&quot;https://gitlab.physik.uni-muenchen.de/LDAP_ls-schollwoeck/svm-order-params/blob/master/README.md&quot;&gt;README file&lt;/a&gt; explains how to build, use, and extend our codes to reproduce our findings, or even adapt the framework to your own simulations. (If you intend to do the latter, please feel free to reach out to us, though.)&lt;/p&gt;

&lt;p class=&quot;centered&quot;&gt;&lt;a href=&quot;https://gitlab.physik.uni-muenchen.de/LDAP_ls-schollwoeck/svm-order-params&quot; class=&quot;gitlab&quot;&gt;Source Code on GitLab&lt;/a&gt;
&lt;a href=&quot;https://github.com/jgreitemann/svm-order-params&quot; class=&quot;github&quot;&gt;Source Code on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Sun, 10 Mar 2019 17:10:34 +0000</pubDate>
        <link>https://greitemann.dev/2019/03/10/two-papers-published-in-prb/</link>
        <guid isPermaLink="true">https://greitemann.dev/2019/03/10/two-papers-published-in-prb/</guid>
        
        <category>physics</category>
        
        <category>svm</category>
        
        <category>machine-learning</category>
        
        <category>publishing</category>
        
        
      </item>
    
      <item>
        <title>Recursive visitors from fixed-point combinators</title>
        <description>&lt;!-- Intro --&gt;

&lt;h4 id=&quot;variadically-inheriting-from-lambdas&quot;&gt;Variadically inheriting from lambdas&lt;/h4&gt;

&lt;p&gt;In the previous post, we left off with a simple visitor functor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Printer&lt;/code&gt; which
provides two overloads for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator()&lt;/code&gt; which are called by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::visit&lt;/code&gt;
depending on the type realized in the variant.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;variant&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&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;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Printer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;got an int: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;void&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&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;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;got a string: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&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;n&quot;&gt;Data&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&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;c1&quot;&gt;// 'got an int: 42'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&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;c1&quot;&gt;// 'got a string: Hello, world!'&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is easy enough, but there’s an even simpler way of achieving the same that
was recently featured by Jason Turner on &lt;a href=&quot;https://www.youtube.com/watch?v=EsUmnLgz8QY&quot;&gt;C++ Weekly Ep. 134&lt;/a&gt;: we define a
generic functor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;visitor&lt;/code&gt; which variadically inherits from a bunch of lambdas:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;visitor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bases&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;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bases&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;operator&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;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;visitor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bases&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;n&quot;&gt;visitor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bases&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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The struct merely contains a variadic &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/using_declaration&quot;&gt;using declaration&lt;/a&gt; (C++17) which
introduces all the call operators of the base classes into the derived class
definition. Lastly, we declare a template parameter deduction guide. This allows
us to construct a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;visitor&lt;/code&gt; through &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/aggregate_initialization&quot;&gt;aggregate initialization&lt;/a&gt; and have the
template parameters inferred. This is non-optional if we want to inherit from
inline lambdas whose type cannot be expressed in closed form. If you want to
know more about the subtleties of this, I highly recommend watching
Jason’s &lt;a href=&quot;https://www.youtube.com/watch?v=EsUmnLgz8QY&quot;&gt;video&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thus, we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;visitor&lt;/code&gt; to quickly define a one-time-use visitor:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&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;kt&quot;&gt;int&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;n&quot;&gt;Data&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Data&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;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visitor&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;got an int: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&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;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;got a string: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&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;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;/figure&gt;

&lt;p&gt;The advantages of this approach are basically those of using lambdas in place of
regular functions in general: we increase readability by keeping the logic in the
place of its (one-time) use. Another upside is the ability to capture variables
from the local scope.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;visitor&lt;/code&gt; template obviously needs to be defined only once. Its definition
is simple enough to stash it into some utility header. In case you a using (a
fairly recent version of) Boost anyway, the new meta-programming library Boost
Hana offers a definition called &lt;a href=&quot;https://www.boost.org/doc/libs/1_61_0/libs/hana/doc/html/group__group-functional.html#ga83e71bae315e299f9f5f9de77b012139&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boost::hana::overload&lt;/code&gt;&lt;/a&gt; straight out of the
box.&lt;/p&gt;

&lt;h4 id=&quot;recursive-visitors&quot;&gt;Recursive visitors&lt;/h4&gt;

&lt;p&gt;One problem arises when we want to call the visitor recursively. Consider the
following example of a variant that’s supposed to represent a value in a JSON
file which can be either a number, a string, or an array or
‘object’ (a.k.a. dictionary or map) of JSON values themselves. JSON also allows
null and Boolean values, which are omitted here for brevity.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&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;nc&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// forward declaration&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// forward declaration&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&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;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&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;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&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;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&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;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&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;/figure&gt;

&lt;p&gt;With this, we can list-initialize a nested &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt; object rather elegantly:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&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;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&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;s&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Can Quantum-Mechanical Description of Physical&quot;&lt;/span&gt;
                  &lt;span class=&quot;s&quot;&gt;&quot; Reality Be Considered Complete?&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;span class=&quot;s&quot;&gt;&quot;year&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1935&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;s&quot;&gt;&quot;authors&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;A. Einstein&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;B. Podolsky&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;N. Rosen&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;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// to be implemented&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In order to serialize a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;json::value&lt;/code&gt; object into valid JSON, we again resort to
the visitor pattern. As a fully-fledged functor class, the visitor might look
like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&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;nc&quot;&gt;printer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&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;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&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;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&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;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quoted&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&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;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'['&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&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;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;','&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'{'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&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;obj&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;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quoted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;':'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&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;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&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;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&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;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&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;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;printer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&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;/figure&gt;

&lt;p&gt;For the above &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main()&lt;/code&gt; function, this will produce the output:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plain&quot; data-lang=&quot;plain&quot;&gt;{&quot;authors&quot;:[&quot;A. Einstein&quot;,&quot;B. Podolsky&quot;,&quot;N. Rosen&quot;,],&quot;title&quot;:&quot;Can Quantum-Mechanical Description of Physical Reality Be Considered Complete&quot;,&quot;year&quot;:1935,}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;which is valid JSON when disregarding the occurrence of trailing commas (which
are technically not allowed).&lt;/p&gt;

&lt;p&gt;Note the use of recursion in the overloads for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;array&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;object&lt;/code&gt;: the visitor
passes itself on to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::visit&lt;/code&gt; which in turn calls its appropriate overloads
for the array elements and values contained in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;object&lt;/code&gt;. When attempting to
realize the same kind of visitor by inheriting from lambdas, we however run into
a problem:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&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;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visitor&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;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&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;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&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;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;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&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;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quoted&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;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&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;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'['&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;c1&quot;&gt;// std::visit(*this, v) &amp;lt;&amp;lt; ',';&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&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;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'{'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&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;obj&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;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quoted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;':'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                        &lt;span class=&quot;c1&quot;&gt;// std::visit(*this, v) &amp;lt;&amp;lt; ',';&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&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;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&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;/figure&gt;

&lt;p&gt;While the overloads for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; are straight-forwardly
implemented (streaming to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;os&lt;/code&gt; which is captured by reference), we have no means
of invoking the visitor recursively. Passing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*this&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::visit&lt;/code&gt; (as
illustrated in the comments) is bound to fail: the lambdas are defined outside
of any class so there is no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this&lt;/code&gt; to be captured. Further, before the lambdas
are fully defined, the derived visitor type is incomplete and could not even be
forward-declared because its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bases...&lt;/code&gt; parameter pack cannot be specified in
closed form.&lt;/p&gt;

&lt;p&gt;This makes a naive implementation through inheritance from lambdas impossible.
Fortunately, the situation can be salvaged using a concept from theoretical
computer science that has major implication for recursion in general: the
fixed-point combinator.&lt;/p&gt;

&lt;h4 id=&quot;lambda-calculus&quot;&gt;Lambda calculus&lt;/h4&gt;

&lt;p&gt;Before we introduce the fixed-point combinator, let’s get acquainted with the
weird notation known as &lt;a href=&quot;https://www.youtube.com/watch?v=eis11j_iGMs&quot;&gt;lambda calculus&lt;/a&gt;. The function of one variable that
squares its argument would traditionally be written as \(f(x)=x^2\), or more
mathematically, \(f: \mathbb{R}\to\mathbb{R}, x\mapsto x^2\). In lambda
calculus, this becomes \(f = \lambda x\,.\,x^2\). Note that the expression on
the right-hand side of the equality sign completely defines the function and it
is not even necessary to give it a name (\(f\)). For this reason, lambdas are
often referred to as &lt;em&gt;anonymous functions&lt;/em&gt;. Further, the name of the argument is
just a placeholder, i.e. \(\lambda x\,.\,x^2=\lambda y\,.\,y^2\).&lt;/p&gt;

&lt;p&gt;When a lambda is invoked, i.e. evaluated for a specific value of its argument,
the parentheses may be omitted if this does not cause confusion, e.g.
\((\lambda x\,.\,x^2)\,5=5^2=25\).&lt;/p&gt;

&lt;p&gt;A function of two variables, say \(f(x,y)=y^x\), can be written as
\(\lambda (x,y)\,.\,y^x\), but in many cases it is more convenient to express
the same as a &lt;em&gt;higher-order function&lt;/em&gt;:&lt;/p&gt;

\[f = \lambda x\,.\,\lambda y\,.\,y^x\]

&lt;p&gt;This is to be understood as a function of one variable (\(x\)), returning
functions of another variable (\(y\)). This procedure of going from one function
of two variables to a &lt;em&gt;higher-order function&lt;/em&gt; (one returning functions) of one
variable, is known as &lt;a href=&quot;https://en.wikipedia.org/wiki/Currying&quot;&gt;&lt;em&gt;Currying&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;the-fixed-point-combinator&quot;&gt;The fixed-point combinator&lt;/h4&gt;

&lt;p&gt;Say, we wanted to define the factorial function
\(n! = n\times(n-1)\times\dots\times 2\times 1\) recursively. In traditional
function notation, we’d write&lt;/p&gt;

\[f(n) = \begin{cases}
n\times f(n-1), &amp;amp; n &amp;gt; 0,\\
1, &amp;amp; n = 0.
\end{cases}\]

&lt;p&gt;However, this definition is self-referential: we are using the function \(f\) in
its own definition. We run into deep water when trying to write down the
corresponding lambda expression: lambdas are anonymous, so we don’t have a name
to refer to the thing we are trying to define. Straightforward recursion is not
possible in lambda calculus.&lt;/p&gt;

&lt;p&gt;What we &lt;em&gt;can&lt;/em&gt; do, however, is define a helper function \(g\) of two arguments: a
function \(f\) that we think of as our sought-after factorial function and the
integer \(n\):&lt;/p&gt;

\[g(f, n) = \begin{cases}
n\,f(n-1), &amp;amp; n &amp;gt; 0,\\
1, &amp;amp; n = 0.
\end{cases}\]

&lt;p&gt;There is no recursion happening here, so this may be written as a lambda
expression:&lt;/p&gt;

\[g = \lambda f\,.\,\lambda n\,.\,\begin{cases}
n\,f(n-1), &amp;amp; n &amp;gt; 0,\\
1, &amp;amp; n = 0.
\end{cases}\]

&lt;p&gt;This alone does not constitute a solution, since in order to define the
factorial function itself, we still need to invoke some sort of recursion:&lt;/p&gt;

\[f(n) = g(f, n).\]

&lt;p&gt;If we omit the argument \(n\) for a moment (through currying), this reduces to
\(f = g(f)\) and is called a &lt;em&gt;fixed-point equation&lt;/em&gt;. Solutions for \(f\) that
satisfy this equation are called fixed points since \(g\) maps those to
themselves. Thus, the factorial function \(f\) is a fixed point of the helper
function \(g\).&lt;/p&gt;

&lt;p&gt;How does one find &lt;em&gt;a&lt;/em&gt; fixed point of a function? Turns out that within the
limits of lambda calculus, one can construct a lambda function that maps
functions to (one of) their fixed-point(s). Such a function is called a
&lt;em&gt;fixed-point combinator&lt;/em&gt;. One particular construction is the so-called
&lt;em&gt;Y combinator&lt;/em&gt; which was discovered by Haskell Curry (who already has a
programming language and the Currying procedure named after him). The lambda
expression for the Y combinator looks like this:&lt;/p&gt;

\[\mathsf{Y} = \lambda f \,.\, (\lambda x \,.\, f(x\ x))(\lambda x \,.\, f(x\ x)).\]

&lt;p&gt;This may look intimidating at first, but honestly it’s quite simple. To verify
that it in fact works as advertized, we first apply it to some function \(g\),&lt;/p&gt;

\[\mathsf{Y}g = (\lambda x \,.\, g(x\ x))(\lambda x \,.\, g(x\ x)),\]

&lt;p&gt;where we just replaced the “independent variable” \(f\) with the concrete function
\(g\) we’re acting upon. We follow the same pattern in evaluating the
right-hand side: the first pair of parentheses defines a lambda function of \(x\)
which is then &lt;em&gt;evaluated&lt;/em&gt; at the point given by the second pair of parentheses,
\(\lambda x\,.\, g(x\ x)\),&lt;/p&gt;

\[\mathsf{Y}g = g((\lambda x \,.\, g(x\ x))(\lambda x \,.\, g(x\ x))) = g(\mathsf{Y}g).\]

&lt;p&gt;In the last equality, we have just recovered the expression for \(\mathsf{Y}g\)
from the previous line. Hence, \(\mathsf{Y}g\) is indeed a fixed point of \(g\).&lt;/p&gt;

&lt;p&gt;This immediately yields the solution to our problem of defining the factorial
function \(f\) in lambda calculus: it is simply given by \(f = \mathsf{Y}g\).
The fixed &lt;em&gt;point&lt;/em&gt; in this case is not a number, but a function (of \(n\)), but
that is not a problem. (In fact, numbers &lt;em&gt;are&lt;/em&gt; functions in lambda calculus.)&lt;/p&gt;

&lt;p&gt;Thus, the Y combinator allows the introduction of recursion to lambda calculus
without changing its axioms or explicitly introducing some sense of
self-referentiality into the formalism. In fact, lambda calculus has been proven to
be Turing complete, &lt;em&gt;i.e.&lt;/em&gt; any program can be expressed as a lambda expression.
To learn more, I recommend the videos on &lt;a href=&quot;https://www.youtube.com/watch?v=eis11j_iGMs&quot;&gt;lambda calculus&lt;/a&gt; in general and the
&lt;a href=&quot;https://www.youtube.com/watch?v=9T8A89jgeTI&quot;&gt;Y combinator&lt;/a&gt; in particular on the Computerphile Youtube channel.&lt;/p&gt;

&lt;h4 id=&quot;using-the-fixed-point-combinator-in-c&quot;&gt;Using the fixed-point combinator in C++&lt;/h4&gt;

&lt;p&gt;When we tried to define the recursive visitor to serialize JSON, we faced a
similar problem to the one that lambda calculus faced conceptually when it comes
to recursion. This raises the question of whether we can also solve it by
similar means; the answer to which is of course &lt;em&gt;‘yes’&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We can write a C++ version of the fixed-point combinator:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;utility&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;G&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Y&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;decltype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&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;o&quot;&gt;&amp;amp;&amp;amp;&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;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&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;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&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;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;G&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&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;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;G&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;G&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;n&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;G&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;/figure&gt;

&lt;p&gt;Albeit I called it affectionally &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Y&lt;/code&gt; for brevity, it does not follow the same
construction as the Y combinator, but rather it is actually implemented in a
self-referential way, invoking &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;g&lt;/code&gt; with itself as first argument and then
forwarding any other arguments in the parameter pack &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, to realize the factorial function without any recursion or
captures, we can write:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&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;k&quot;&gt;auto&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;kt&quot;&gt;int&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;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;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;return&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;n&quot;&gt;f&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;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&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;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&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;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// outputs 120&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that we used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; as the argument type in the definition of \(g\), making
this a generic lambda. Thus, the return type cannot be inferred and needs to be
specified with trailing return type syntax.&lt;/p&gt;

&lt;p&gt;The above code compiles with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;g++&lt;/code&gt; 7 or newer, as well as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clang++&lt;/code&gt; 5 or newer.
Clang actually evaluates the expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(5)&lt;/code&gt; at compile time with optimization
level &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-O3&lt;/code&gt;. GCC does not, but can be forced to do so by declaring the variables
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;g&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt;, as well as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Y::operator()&lt;/code&gt; function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constexpr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Boost provides a similar implementation for the fixed-point combinator in the
new Hana library called &lt;a href=&quot;https://www.boost.org/doc/libs/1_61_0/libs/hana/doc/html/group__group-functional.html#ga1393f40da2e8da6e0c12fce953e56a6c&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boost::hana::fix&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;recursive-serialization-of-json&quot;&gt;Recursive serialization of JSON&lt;/h4&gt;

&lt;p&gt;Finally, let’s bring it all together and implement the serialization of JSON
using a variant visitor derived from lambdas, and by reintroducing recursion
using the fixed-point combinator.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&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;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visitor&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;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&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;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&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;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;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&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;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quoted&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;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&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;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'['&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&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;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&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;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'{'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&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;obj&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;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quoted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;':'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&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;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&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;p&quot;&gt;}},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&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;/figure&gt;

&lt;p&gt;Note the changes compared to the version at the beginning of this post: the
individual lambda overloads have an additional first argument &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto self&lt;/code&gt; and
the whole &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;visitor&lt;/code&gt; is wrapped in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Y&lt;/code&gt; combinator.&lt;/p&gt;

&lt;p&gt;While the contents of this post are certainly a lot to take in, especially so if
lambda calculus is new to you, the resulting solutions are quite simple to use
and I’ve found myself using them loads since. It’s a case where concepts from
theoretical computer science can be applied to real code.&lt;/p&gt;

</description>
        <pubDate>Sun, 03 Feb 2019 15:34:57 +0000</pubDate>
        <link>https://greitemann.dev/2019/02/03/recursive-visitors-from-fixed-point-combinators/</link>
        <guid isPermaLink="true">https://greitemann.dev/2019/02/03/recursive-visitors-from-fixed-point-combinators/</guid>
        
        <category>c++</category>
        
        <category>functional</category>
        
        
      </item>
    
      <item>
        <title>Type safety, variants, and visitors</title>
        <description>&lt;h4 id=&quot;variants-vs-unions&quot;&gt;Variants vs. unions&lt;/h4&gt;

&lt;p&gt;C++17 came with library support for type-safe unions in the form of
&lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/variant&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::variant&lt;/code&gt;&lt;/a&gt;. A variant will hold exactly one instance of its template
parameter types. For example, objects of type&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&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;/figure&gt;

&lt;p&gt;can hold either an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;, or a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;. In plain old C, one would use a
&lt;em&gt;union type&lt;/em&gt; in this situation:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;k&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;A variable of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar&lt;/code&gt; could hence be accessed as an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; by using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt;
member and as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt; by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt;, implicitly performing an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reinterpret_cast&lt;/code&gt; of the data. &lt;a href=&quot;https://youtu.be/L06nbZXD2D0&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reinterpret_cast&lt;/code&gt;s are frowned upon&lt;/a&gt;, and
rightly so, as they open the door to undefined behavior, and this extends to
unions. It is up to the programmer to keep track of the realization that is
used. For member types with non-trivial constructors or destructors (such as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;), one has to carefully provide those explicitly to not risk memory
leaks or segfaults. In practice, one will almost always create a &lt;em&gt;tagged union&lt;/em&gt;,
i.e. associate the union with a tag (index) to indicate the realized
alternative.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::variant&lt;/code&gt; is in essence such a tagged union. This is also apparent from
the sizeof the types: on a 64-bit machine &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(bar)&lt;/code&gt; is 32 bytes which is
identical to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(std::string)&lt;/code&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; alternative being significantly
smaller at 4 bytes. In contrast, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sizeof(foo)&lt;/code&gt; yields 40 bytes, where the
additional 8 bytes are reserved for the index (or tag) which is itself a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::size_t&lt;/code&gt;. Thus, the variant knows which alternative it holds, lets us test
against it, and provides safe constructors and destructors. It is still possible
to attempt to access the wrong alternative, but this will be caught at run-time
and an exception will be thrown.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello, world&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// realizes the std::string alternative&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&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;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// throws std::bad_variant_access&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Thus, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt; will not be assigned with the first four bytes of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::string&lt;/code&gt;
object; no undefined behavior can arise. This renders &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::variant&lt;/code&gt; a type-safe
replacement of unions.&lt;/p&gt;

&lt;p&gt;When the realized alternative is not apparent from the context, one will often
end up with code that tests for each of the realizations and conditionally
executes a code branch:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;holds_alternative&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&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;f&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;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;got an int: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&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;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;got a string: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&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;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;/figure&gt;

&lt;p&gt;This can get hairy when a lot of alternatives exist. If additional alternatives
are added to the variant, the above code would execute the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;else&lt;/code&gt; branch for any
new non-&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; type. This is not a big deal since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::get&lt;/code&gt; would throw if used
improperly; still, it would be preferable if the compiler had a way of checking
for an exhaustive treatment of all possible alternatives. Visitors can achieve
just that.&lt;/p&gt;

&lt;h4 id=&quot;the-visitor-pattern&quot;&gt;The visitor pattern&lt;/h4&gt;

&lt;p&gt;The main goal of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Visitor_pattern#C++_example&quot;&gt;visitor pattern&lt;/a&gt; is to achieve a separation between code
that defines a data structure and that which operates on the data. This makes
it well-suited to variants, since one would typically not derive directly from
the variant, but work with the generic variant type, but still be able to
perform arbitrary operations one the data contained in the variant.&lt;/p&gt;

&lt;p&gt;The visitor pattern however predates &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::variant&lt;/code&gt; or even &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boost::variant&lt;/code&gt;. It
originates from object-oriented programming where dynamic dispatch is used to
select the proper overload. Consider the following program:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// forward declaration&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// forward declaration&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Abstract Visitor interface&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Visitor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&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;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&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;mi&quot;&gt;0&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;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Visitor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&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;mi&quot;&gt;0&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;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Visitor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;v&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;k&quot;&gt;this&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;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&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;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&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;o&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;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Visitor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;v&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;k&quot;&gt;this&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;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Printer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Visitor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;got an int: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;void&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;got a string: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&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;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&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;n&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;String&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;s&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&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;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;i&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;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&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;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{});&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 'got an int: 42'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&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;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{});&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 'got a string: Hello, world!'&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Data&lt;/code&gt; is the common abstract base class of two data “structures”, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Int&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String&lt;/code&gt;. These must implement a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;visit&lt;/code&gt; member function, invoking the call
operator on a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Visitor&lt;/code&gt; functor that is passed along. The bodies of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Int::visit&lt;/code&gt;
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String::visit&lt;/code&gt; may look alike but in fact these invoke different overloads
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator()&lt;/code&gt; since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*this&lt;/code&gt; has a different type (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Int&amp;amp;&lt;/code&gt; vs. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String&amp;amp;&lt;/code&gt;). The
concrete visitor class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Printer&lt;/code&gt; in turn derives from the interface &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Visitor&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Crucially, the data classes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Int&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String&lt;/code&gt; don’t need any knowledge of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Printer&lt;/code&gt;. The user may implement arbitrary visitors by deriving from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Visitor&lt;/code&gt;
and handling each of the alternatives in a separate overload of the call
operator. No explicit type checks and no downcasts are required which makes this
pattern quite elegant. On the downside, the whole thing relies on run-time
polymorphism and dynamic dispatch and the associated &lt;a href=&quot;https://en.wikipedia.org/wiki/Virtual_method_table&quot;&gt;vtable&lt;/a&gt; lookups incur
a significant performance cost (which may be partly negated if devirtualization
optimization can be used). The derived classes will typically also need to be
allocated dynamically, adding an additional level of indirection and breaking
memory locality compared to variants.&lt;/p&gt;

&lt;h4 id=&quot;visitation-of-stdvariant&quot;&gt;Visitation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::variant&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;Rather than relying on dynamic polymorphism, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::variant&lt;/code&gt; uses the visitor
pattern to achieve the same thing with static polymorphism (i.e. generic
programming). &lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/variant/visit&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::visit&lt;/code&gt;&lt;/a&gt; is called on an arbitrary variant and a
visitor functor which similarly provides overloads of the call operator (but is
not derived from any interface). Internally, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::visit&lt;/code&gt; will use
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;holds_alternative&lt;/code&gt; successively and call the visitor with a reference to its
contents. This ensures that the visitor handles all alternatives of the variant,
giving a hard compiler error should any overload be missing. The call of the
visitor is dispatched statically, meaning no vtable lookups are necessary, the
function bodies can be inlined and branch prediction and vectorization can be used.&lt;/p&gt;

&lt;p&gt;The equivalent to the above example program, realized with variants, becomes
much simpler:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;variant&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&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;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Printer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;got an int: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;void&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&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;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;got a string: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&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;n&quot;&gt;Data&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&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;c1&quot;&gt;// 'got an int: 42'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&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;c1&quot;&gt;// 'got a string: Hello, world!'&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Don’t use unions anymore. Variants offer type safety and better
compiler diagnostics with less boilerplate. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::visit&lt;/code&gt; makes it easy to apply
the visitor pattern without setting up intricate class hierarchies, while
achieving data/algorithm separation.&lt;/p&gt;

</description>
        <pubDate>Sun, 21 Oct 2018 19:47:08 +0000</pubDate>
        <link>https://greitemann.dev/2018/10/21/type-safety-variants-and-visitors/</link>
        <guid isPermaLink="true">https://greitemann.dev/2018/10/21/type-safety-variants-and-visitors/</guid>
        
        <category>c++</category>
        
        
      </item>
    
  </channel>
</rss>
