<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Scala - Tag - Notes about stuff</title>
        <link>/tags/scala/</link>
        <description>Scala - Tag - Notes about stuff</description>
        <generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Thu, 28 May 2026 06:51:15 &#43;0200</lastBuildDate><atom:link href="/tags/scala/" rel="self" type="application/rss+xml" /><item>
    <title>Scala, Rust</title>
    <link>/posts/2026-05-28_scala_and_rust/</link>
    <pubDate>Thu, 28 May 2026 06:51:15 &#43;0200</pubDate>
    <author>Kamila Chyla</author>
    <guid>/posts/2026-05-28_scala_and_rust/</guid>
    <description><![CDATA[<h1 id="exploration">Exploration</h1>
<p>Quick summary of recently reviewed concepts:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">| Concept        | Scala 3                    | Rust                          |
</span></span><span class="line"><span class="cl">|----------------+----------------------------+-------------------------------|
</span></span><span class="line"><span class="cl">| Type classes   | given/using, derives       | Traits + blanket impls        |
</span></span><span class="line"><span class="cl">| HKTs           | F[_] natively              | Not directly (GATs partial)   |
</span></span><span class="line"><span class="cl">| Error handling | Either, Validated, EitherT | Result, ?, thiserror/anyhow   |
</span></span><span class="line"><span class="cl">| Zero-cost types| opaque type                | newtypes, zero-sized types    |
</span></span><span class="line"><span class="cl">| Closures       | Function1, SAM types       | Fn/FnMut/FnOnce               |</span></span></code></pre></div></div>
<p>Other interesting observations:</p>
<ul>
<li>cognitive load seems to be much higher when I look at Scala code compared to when I look at Rust&rsquo;s (tbh I wasn&rsquo;t expecting this)</li>
<li>Scala type system expressiveness is huge; I&rsquo;m not sure I undestand where its depth ends</li>
</ul>
<h1 id="scala-tooling-imporessions">Scala tooling imporessions</h1>
<p>Scala tooling sometimes seem a bit brittle:</p>
<ol>
<li>Code completion sometimes stops working (metals in Emacs/Vim).</li>
<li>It is more stable on Intellij in general. Sometimes it has trouble resolving dependencies added to ``build.sbt` though.</li>
<li>Intellij sometimes states with its curly underline that an expression is invalid whereas the problem is elsewhere completely (compared to very precise and dev-friendly compiler errors from Rust compiler, it is just not up to my expectations)</li>
</ol>
<h1 id="libs-impressions">Libs impressions</h1>
<ul>
<li><a href="https://typelevel.org/cats/" target="_blank" rel="noopener noreffer ">cats</a> is interesting to read, inspires my imagination for sure, but quite challenging if I want to apply those concepts</li>
<li><a href="https://typelevel.org/cats-effect/" target="_blank" rel="noopener noreffer ">cats-effects</a> and typelevel libs (eg <a href="https://http4s.org/v1/docs/quickstart.html" target="_blank" rel="noopener noreffer ">HTTP4s</a>) form an ecosystem that is even harder, something im my head just does not want this complexity</li>
<li>looking at <a href="https://zio.dev/" target="_blank" rel="noopener noreffer ">ZIO</a> and <a href="https://ziohttp.com/" target="_blank" rel="noopener noreffer ">ZIO HTTP</a>: I&rsquo;m positively surprised with the quality of documentation; yesterday I was able to write a small http server and I had fun :)</li>
<li><a href="https://monix.io/" target="_blank" rel="noopener noreffer ">Monix</a> - compared to ZIO - is rather low-level; no Fibers as &ldquo;first class citizens&rdquo; (you need to <code>Task.fork</code>), there is CancellableFuture</li>
</ul>
<h1 id="new-resource">New resource</h1>
<p>I found one resource that is - I think - worth exproring: <a href="https://softwarepatternslexicon.com/scala/" target="_blank" rel="noopener noreffer ">Software Patterns Lexicon</a> (the link is for Scala, but other languages are there).</p>
]]></description>
</item>
<item>
    <title>Define a reusable and lazy pipeline</title>
    <link>/posts/2026-04-06_define_a_reusable_and_lazy_pipeline/</link>
    <pubDate>Mon, 06 Apr 2026 17:48:00 &#43;0200</pubDate>
    <author>Kamila Chyla</author>
    <guid>/posts/2026-04-06_define_a_reusable_and_lazy_pipeline/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/image.png" referrerpolicy="no-referrer">
            </div><h1 id="the-problem">The problem</h1>
<p>I have the idea of a pipeline: it is defined once, it can be reused and when called, it changes its state but does not evaluate eagerly, because it could be &ldquo;fed&rdquo; from an infinite source of data.</p>
<p>For example:</p>
<ul>
<li>all integers which are multiple of 13 and has in its binary representation more ones than zeroes</li>
<li>indices of bytes read from /dev/random which are ascii characters</li>
</ul>
<p>Perhaps there are two separate issues I&rsquo;m thinking about here:</p>
<ol>
<li>Is the pipeline creating intermediate collections when processing items through the pipeline?
For example, in Scala, all intermediate operations <em>do</em> create a collection (each map and filter)</li>
<li>When exactly is the pipeline execution triggered?</li>
<li>Can the pipeline computation be reused with different collection? Does it need a collection at all?</li>
</ol>
<h2 id="in-scala">In scala</h2>
<p>Note: see this insightful comment on SO: <a href="https://stackoverflow.com/questions/31664918/does-scala-has-intermediate-terminal-ops-as-java8-has" target="_blank" rel="noopener noreffer ">https://stackoverflow.com/questions/31664918/does-scala-has-intermediate-terminal-ops-as-java8-has</a></p>
<p>In the collections library Scala makes a distinction between <em>strict</em> and <em>lazy</em> evaluation. A mechanism for lazy evaluation is called <em>view</em>. By default collections evaluate eagerly <em>at every step</em>.</p>
<p>Let&rsquo;s create an efectful operation that doubles its input and prints it:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">def</span> <span class="n">reportDouble</span><span class="o">(</span><span class="n">v</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="o">{</span> <span class="n">println</span><span class="o">(</span><span class="s">s&#34;Reporting </span><span class="si">$v</span><span class="s"> -&gt; </span><span class="si">${</span><span class="n">v</span><span class="o">*</span><span class="mi">2</span><span class="si">}</span><span class="s">&#34;</span><span class="o">);</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">v</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">l</span> <span class="k">=</span> <span class="nc">List</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">,</span> <span class="mi">5</span><span class="o">,</span> <span class="mi">10</span><span class="o">,</span> <span class="mi">34</span><span class="o">,</span> <span class="mi">78</span><span class="o">,</span> <span class="mi">126</span><span class="o">)</span></span></span></code></pre></div></div>
<p>Now, each <code>map</code> or <code>filter</code> on a <code>List</code> evaluates eagerly and produces a list immediately, and the map &ldquo;traverses&rdquo; all elements:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="n">l</span><span class="o">.</span><span class="n">map</span><span class="o">(</span><span class="n">reportDouble</span><span class="o">).</span><span class="n">filter</span><span class="o">(</span><span class="k">_</span> <span class="o">&gt;</span> <span class="mi">3</span><span class="o">).</span><span class="n">take</span><span class="o">(</span><span class="mi">3</span><span class="o">).</span><span class="n">foreach</span><span class="o">(</span><span class="n">println</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="k">#</span> <span class="nc">Reporting</span> <span class="mi">1</span> <span class="o">-&gt;</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="k">#</span> <span class="nc">Reporting</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="k">#</span> <span class="nc">Reporting</span> <span class="mi">5</span> <span class="o">-&gt;</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="k">#</span> <span class="nc">Reporting</span> <span class="mi">10</span> <span class="o">-&gt;</span> <span class="mi">20</span>
</span></span><span class="line"><span class="cl"><span class="k">#</span> <span class="nc">Reporting</span> <span class="mi">34</span> <span class="o">-&gt;</span> <span class="mi">68</span>
</span></span><span class="line"><span class="cl"><span class="k">#</span> <span class="nc">Reporting</span> <span class="mi">78</span> <span class="o">-&gt;</span> <span class="mi">156</span>
</span></span><span class="line"><span class="cl"><span class="k">#</span> <span class="nc">Reporting</span> <span class="mi">126</span> <span class="o">-&gt;</span> <span class="mi">252</span>
</span></span><span class="line"><span class="cl"><span class="k">#</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="k">#</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="k">#</span> <span class="mi">20</span></span></span></code></pre></div></div>
<h3 id="iterator">Iterator</h3>
<p>We can also create an iterator. Note how the first value gets through the map, even if we haven&rsquo;t explicitely trigerred it. However, the first element is not actually missing, we will get it eventually when we do <code>next</code> or use other <code>terminal</code> operations causing traversal and evaluation of pipeline operations:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">scala</span><span class="o">&gt;</span>  <span class="k">val</span> <span class="n">it</span> <span class="k">=</span> <span class="n">l</span><span class="o">.</span><span class="n">iterator</span><span class="o">.</span><span class="n">map</span><span class="o">(</span><span class="n">reportDouble</span><span class="o">).</span><span class="n">filter</span><span class="o">(</span><span class="k">_</span> <span class="o">&gt;</span> <span class="mi">3</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">1</span> <span class="o">-&gt;</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">it</span><span class="k">:</span> <span class="kt">Iterator</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span> <span class="k">=</span> <span class="n">non</span><span class="o">-</span><span class="n">empty</span> <span class="n">iterator</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">scala</span><span class="o">&gt;</span> <span class="n">it</span><span class="o">.</span><span class="n">next</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">res0</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">scala</span><span class="o">&gt;</span> <span class="n">it</span><span class="o">.</span><span class="n">next</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">5</span> <span class="o">-&gt;</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">res1</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">scala</span><span class="o">&gt;</span> <span class="n">it</span><span class="o">.</span><span class="n">toList</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">10</span> <span class="o">-&gt;</span> <span class="mi">20</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">34</span> <span class="o">-&gt;</span> <span class="mi">68</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">78</span> <span class="o">-&gt;</span> <span class="mi">156</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">126</span> <span class="o">-&gt;</span> <span class="mi">252</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">res2</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span> <span class="k">=</span> <span class="nc">List</span><span class="o">(</span><span class="mi">20</span><span class="o">,</span> <span class="mi">68</span><span class="o">,</span> <span class="mi">156</span><span class="o">,</span> <span class="mi">252</span><span class="o">)</span></span></span></code></pre></div></div>
<h3 id="reusability---iterator-is-not-reusable">Reusability - Iterator is not reusable</h3>
<p>The iterator approach allows to build a pipeline and evaluate elements when needed. However, we are not able to reuse the pipeline: once the iterator is exhausted, we&rsquo;re done. We need to create a new iterator, repeating the pipeline code.
It seems the pipeline needs to have a collection to work on attached to it. Or, in other words, there is <em>no such thing</em> as a pipeline here, I guess.</p>
<h2 id="being-lazy---scala-views">Being lazy - scala views</h2>
<p><code>views</code> make the pipeline lazy - but this happens only if we have whole pipeline and we don&rsquo;t store e.g. <code>map</code> result in a val (then - we have no laziness, but eager creation of strict collection). This is the part that was very confusing to me :)</p>
<p>If I create a view and try to map, I am forcing the evaluation! As you can see, all elements of the list get evaluated and printed, and <code>xv</code> hols a SeqView of all evaluated, already-computed values:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">#</span> <span class="nc">BAD</span> <span class="o">-</span> <span class="n">asiigning</span> <span class="n">l</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">map</span> <span class="n">to</span> <span class="k">val</span>
</span></span><span class="line"><span class="cl"><span class="n">scala</span><span class="o">&gt;</span> <span class="k">val</span> <span class="n">xv</span> <span class="k">=</span> <span class="n">l</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">map</span><span class="o">(</span><span class="n">reportDouble</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">1</span> <span class="o">-&gt;</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">5</span> <span class="o">-&gt;</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">10</span> <span class="o">-&gt;</span> <span class="mi">20</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">34</span> <span class="o">-&gt;</span> <span class="mi">68</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">78</span> <span class="o">-&gt;</span> <span class="mi">156</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">126</span> <span class="o">-&gt;</span> <span class="mi">252</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">xv</span><span class="k">:</span> <span class="kt">scala.collection.SeqView</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span> <span class="k">=</span> <span class="nc">SeqView</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="mi">4</span><span class="o">,</span> <span class="mi">10</span><span class="o">,</span> <span class="mi">20</span><span class="o">,</span> <span class="mi">68</span><span class="o">,</span> <span class="mi">156</span><span class="o">,</span> <span class="mi">252</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">#</span> <span class="nc">GOOD</span> <span class="o">-</span> <span class="n">reportDouble</span> <span class="n">does</span> <span class="n">not</span> <span class="n">run</span> <span class="n">again</span><span class="o">,</span> <span class="n">values</span> <span class="n">are</span> <span class="n">materialized</span> <span class="n">in</span> <span class="n">xv</span>
</span></span><span class="line"><span class="cl"><span class="n">scala</span><span class="o">&gt;</span> <span class="n">xv</span><span class="o">.</span><span class="n">filter</span><span class="o">(</span><span class="k">_</span> <span class="o">&lt;</span> <span class="mi">20</span><span class="o">).</span><span class="n">take</span><span class="o">(</span><span class="mi">3</span><span class="o">).</span><span class="n">foreach</span><span class="o">(</span><span class="n">println</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="n">xv</span><span class="o">.</span><span class="n">filter</span><span class="o">(</span><span class="k">_</span> <span class="o">&lt;</span> <span class="mi">20</span><span class="o">).</span><span class="n">take</span><span class="o">(</span><span class="mi">3</span><span class="o">).</span><span class="n">foreach</span><span class="o">(</span><span class="n">println</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">1</span> <span class="o">-&gt;</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">5</span> <span class="o">-&gt;</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="mi">10</span></span></span></code></pre></div></div>
<p>Lesson: <em>keep entire chaing on one expression</em> if what I need is the laziness.</p>
<h3 id="view-and-reusability">View and reusability</h3>
<p>Unlike <code>iterator</code>, <code>view</code> <em>is</em> reusable - it holds a reference to the original connection, and it reconstructs the pipeline on each terminal operation, doing a minimal, lazy work on each call (starting fresh from the begining, with minimal processing of what is necessary) - the map is not triggered:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="n">scala</span><span class="o">&gt;</span> <span class="k">val</span> <span class="n">xv</span> <span class="k">=</span> <span class="n">l</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">map</span><span class="o">(</span><span class="n">reportDouble</span><span class="o">).</span><span class="n">filter</span><span class="o">(</span><span class="k">_</span> <span class="o">&lt;</span> <span class="mi">20</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">1</span> <span class="o">-&gt;</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">5</span> <span class="o">-&gt;</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">10</span> <span class="o">-&gt;</span> <span class="mi">20</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">34</span> <span class="o">-&gt;</span> <span class="mi">68</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">78</span> <span class="o">-&gt;</span> <span class="mi">156</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">126</span> <span class="o">-&gt;</span> <span class="mi">252</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">xv</span><span class="k">:</span> <span class="kt">scala.collection.View</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span> <span class="k">=</span> <span class="nc">View</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="mi">4</span><span class="o">,</span> <span class="mi">10</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">scala</span><span class="o">&gt;</span> <span class="n">xv</span><span class="o">.</span><span class="n">take</span><span class="o">(</span><span class="mi">3</span><span class="o">).</span><span class="n">foreach</span><span class="o">(</span><span class="n">println</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">1</span> <span class="o">-&gt;</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">5</span> <span class="o">-&gt;</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="mi">10</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">scala</span><span class="o">&gt;</span> <span class="n">xv</span><span class="o">.</span><span class="n">take</span><span class="o">(</span><span class="mi">2</span><span class="o">).</span><span class="n">foreach</span><span class="o">(</span><span class="n">println</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">1</span> <span class="o">-&gt;</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="mi">4</span></span></span></code></pre></div></div>
<p>The answer to reusability is: yes, views can be reused. They still are attached to the source collection- you cannot define a pipeline and apply it to a different collection.</p>
<h3 id="lazylist">LazyList</h3>
<p>Docs: <a href="https://www.scala-lang.org/api/2.13.4/scala/collection/immutable/LazyList.html" target="_blank" rel="noopener noreffer ">LazyList</a></p>
<p><code>LazyList</code>s can be infinite, are lazy and their values are memoized. What does it mean? The pipeline would be evaluated in a way that elements that were previously accessed will not be evaluated again.</p>
<p>The usecase for LazyList are infinite collections which we don&rsquo;t want to evaluate eagerly (like in the beautiful fibonacci example) and for finite collections don&rsquo;t give any benefit over <code>view</code>s&quot;</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">LazyList</span><span class="o">.</span><span class="n">from</span><span class="o">(</span><span class="n">l</span><span class="o">).</span><span class="n">map</span><span class="o">(</span><span class="n">reportDouble</span><span class="o">).</span><span class="n">filter</span><span class="o">(</span><span class="k">_</span> <span class="o">&gt;</span> <span class="mi">3</span><span class="o">).</span><span class="n">take</span><span class="o">(</span><span class="mi">3</span><span class="o">).</span><span class="n">foreach</span><span class="o">(</span><span class="n">println</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">1</span> <span class="o">-&gt;</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="mi">4</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">5</span> <span class="o">-&gt;</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="nc">Reporting</span> <span class="mi">10</span> <span class="o">-&gt;</span> <span class="mi">20</span>
</span></span><span class="line"><span class="cl"><span class="mi">20</span></span></span></code></pre></div></div>
<h3 id="conclusions-for-scala">Conclusions for Scala</h3>
<p>For lazy, efficient pipelines it is a good idea to use a<code>view</code>, and remember to keep the chain *in one expression&quot;.</p>
<p>Reusability of a pipeline across different collections is not possible: the best I can think of is to create a function that takes a collection or an iterator. Similar to Java Streams, we can talk about terminal and intermediate operations, but intermediate does not mean lazy in this case, becasue Scala collections API is by default <em>strict</em> and will evaluate <em>everyting</em> unless you <em>opt out</em> using <em>views</em> (now: think about Rust - it is lazy by default).</p>
<p>At least this is my understanding.</p>
<h2 id="python">Python</h2>
<p>In Python, mapping and filtering operations leave you with lazy iterator objects which by itself do not trigger anything - nothing is evaluated until consumed.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-python">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">li</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">34</span><span class="p">,</span> <span class="mi">78</span><span class="p">,</span> <span class="mi">126</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">reportDouble</span><span class="p">(</span><span class="n">v</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Reporting </span><span class="si">{v}</span><span class="s2"> -&gt; {v*2}&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">v</span> <span class="o">*</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">map</span><span class="p">(</span><span class="n">reportDouble</span><span class="p">,</span> <span class="n">li</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># &lt;map at 0x7b77bd1bf5e0&gt; -- no output</span>
</span></span><span class="line"><span class="cl"><span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">v</span><span class="p">:</span> <span class="n">v</span> <span class="o">&lt;</span> <span class="mi">15</span><span class="p">,</span> <span class="nb">map</span><span class="p">(</span><span class="n">reportDouble</span><span class="p">,</span> <span class="n">li</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="c1"># &lt;filter at 0x7b77bc4fd9c0&gt; -- still nothing</span></span></span></code></pre></div></div>
<p>Evaluation happens element-by-element only when something consumes those iterators. One needs to explicitely create a list out of the iterators created by <code>map</code> or <code>filter</code>.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-python">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">fm</span> <span class="o">=</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">v</span><span class="p">:</span> <span class="n">v</span> <span class="o">&lt;</span> <span class="mi">15</span><span class="p">,</span> <span class="nb">map</span><span class="p">(</span><span class="n">reportDouble</span><span class="p">,</span> <span class="n">li</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">fm</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Reporting 1 -&gt; 2</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Reporting 2 -&gt; 4</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Reporting 5 -&gt; 10</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Reporting 10 -&gt; 20 (processed but filtered out)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Reporting 34 -&gt; 68  (processed but filtered out)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># ...</span>
</span></span><span class="line"><span class="cl"><span class="c1"># result: [2, 4, 10]</span></span></span></code></pre></div></div>
<p>Note that <em>all</em> elements get processed  - map and filter don&rsquo;t do any short-circuiting&hellip;</p>
<p>I remember that Python has <code>itertools</code> module, perhaps I can find some answers there?</p>
<p>Build-in <code>map</code> and <code>filter</code> suffer from <em>reusability problem</em>: they produce just single-use iterators:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-python">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">fm</span> <span class="o">=</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">v</span><span class="p">:</span> <span class="n">v</span> <span class="o">&lt;</span> <span class="mi">15</span><span class="p">,</span> <span class="nb">map</span><span class="p">(</span><span class="n">reportDouble</span><span class="p">,</span> <span class="n">li</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">list</span><span class="p">(</span><span class="n">fm</span><span class="p">)</span>  <span class="c1"># works, prints all, returns [2, 4, 10]</span>
</span></span><span class="line"><span class="cl"><span class="nb">list</span><span class="p">(</span><span class="n">fm</span><span class="p">)</span>  <span class="c1"># returns [] - iterator is exhausted</span></span></span></code></pre></div></div>
<h3 id="the-fix---wrap-it">The Fix - wrap it</h3>
<p>If we wrap the source in a function then each time the function is called, new iterator will be created, allowing to reuse the pipeline:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-python">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">pipeline</span><span class="p">(</span><span class="n">source</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">v</span><span class="p">:</span> <span class="n">v</span> <span class="o">&lt;</span> <span class="mi">15</span><span class="p">,</span> <span class="nb">map</span><span class="p">(</span><span class="n">reportDouble</span><span class="p">,</span> <span class="n">source</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">list</span><span class="p">(</span><span class="n">pipeline</span><span class="p">(</span><span class="n">li</span><span class="p">))</span> <span class="c1"># [2, 4, 10]</span>
</span></span><span class="line"><span class="cl"><span class="nb">list</span><span class="p">(</span><span class="n">pipeline</span><span class="p">(</span><span class="n">li</span><span class="p">))</span> <span class="c1"># [2, 4, 10] - works again &lt;- new iterator</span></span></span></code></pre></div></div>
<p>If the pipeline is complex (or we want to keep complex state, eg. when traversing a tree) and we want multiple conditions or early exit, or we want it to be <em>lazy</em> then we should use generators, and also <code>itertools.islice</code>(<a href="https://docs.python.org/3/library/itertools.html#itertools.islice" target="_blank" rel="noopener noreffer ">python doc</a>) which is an equivalet of <code>take</code>:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-python">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">gen_pipeline</span><span class="p">(</span><span class="n">source</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">  <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">source</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">doubled</span> <span class="o">=</span> <span class="n">reportDouble</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">doubled</span> <span class="o">&lt;</span> <span class="mi">15</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">      <span class="k">yield</span> <span class="n">doubled</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># lazy short-cicquit, take only 3 elems</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">itertools</span>
</span></span><span class="line"><span class="cl"><span class="nb">list</span><span class="p">(</span><span class="n">itertools</span><span class="o">.</span><span class="n">islice</span><span class="p">(</span><span class="n">gen_pipeline</span><span class="p">(</span><span class="n">li</span><span class="p">),</span> <span class="mi">3</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Reporting 1 -&gt; 2</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Reporting 2 -&gt; 4</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Reporting 5 -&gt; 10</span>
</span></span><span class="line"><span class="cl"><span class="c1"># result: [2, 4, 10] - stops after 3, does not process rest</span>
</span></span><span class="line"><span class="cl"><span class="c1"># </span></span></span></code></pre></div></div>
<h3 id="python---summary">Python - summary</h3>
<p>Python&rsquo;s <code>map</code>/<code>filter</code> are lazy but single-use. The language, as far as I know, does not have a &ldquo;pipeline&rdquo; construct - the most similar thing I can think of is a <em>function</em> wich can be used to start new iterators when needed - a callable is the reusable abstraction. It cannot be, however, independent from the source: you always need to have a collection or iterator to iterate over.</p>
<p>I once came quite close to the idea of a structure of computations that is independent on the collection - but never actually tried it. It is time to dive into&hellip;</p>
<h2 id="clojure">Clojure</h2>
<p>&hellip; clojure&rsquo;s transducers.</p>
<p>Perhaps the closest concept to what I am searching for is the <em>transducer</em> <a href="https://clojure.org/reference/transducers" target="_blank" rel="noopener noreffer ">concept</a> I encountered in clojure. It seems like a definition or composition of operations which
do not require a collection and can exist by itself. The documentation states that operations such as <code>map</code>, <code>filter</code> or <code>take</code> (for others see also <a href="https://clojure.org/api/cheatsheet" target="_blank" rel="noopener noreffer ">cheatscheet</a>) create transducers:</p>
<p>What the docs say is:</p>
<blockquote>
<p>Most sequence functions included in Clojure have an arity that produces a transducer. This arity omits the input collection; the inputs will be supplied by the process applying the transducer. Note: this reduced arity is not currying or partial application.</p>
</blockquote>
<p>Deriving from the documentation example, I can create <code>xf</code> transducer which is a composition of other transducers (<code>comp</code> is composing right-to-left, so the mental model for final transucer operation is that it executes left-to-right, first filtering, then mapping and finally taking two elements). Final reducing operation is &ldquo;+&rdquo; here; transduced sequence before addition can be retrieved by using <code>(into [] ...)</code> form:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-clojure">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-clojure" data-lang="clojure"><span class="line"><span class="cl"><span class="nv">user&gt;</span> <span class="p">(</span><span class="k">def </span><span class="nv">xf</span> <span class="p">(</span><span class="nb">comp </span><span class="p">(</span><span class="nb">filter </span><span class="nv">odd?</span><span class="p">)</span> <span class="p">(</span><span class="nb">map </span><span class="nv">inc</span><span class="p">)</span> <span class="p">(</span><span class="nb">take </span><span class="mi">2</span><span class="p">)))</span> 
</span></span><span class="line"><span class="cl"><span class="o">#</span><span class="ss">&#39;user/xf</span>
</span></span><span class="line"><span class="cl"><span class="nv">user&gt;</span> <span class="p">(</span><span class="nf">transduce</span> <span class="nv">xf</span> <span class="nb">+ </span><span class="p">[</span><span class="mi">3</span>,<span class="mi">4</span>,<span class="mi">5</span>,<span class="mi">6</span>,<span class="mi">7</span>,<span class="mi">8</span>,<span class="mi">9</span>,<span class="mi">10</span>,<span class="mi">11</span>,<span class="mi">12</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="nv">user&gt;</span> <span class="p">(</span><span class="nb">into </span><span class="p">[]</span> <span class="nv">xf</span>  <span class="p">[</span><span class="mi">3</span>,<span class="mi">4</span>,<span class="mi">5</span>,<span class="mi">6</span>,<span class="mi">7</span>,<span class="mi">8</span>,<span class="mi">9</span>,<span class="mi">10</span>,<span class="mi">11</span>,<span class="mi">12</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="mi">4</span> <span class="mi">6</span><span class="p">]</span></span></span></code></pre></div></div>
<p>What happens when I define xf such that it prints an element, let&rsquo;s say: very early, before <code>filter</code>? Would It then print everything? At least, it will not at the time transducer is defined. I expect it to fire for all vec elements, however. I aslo expect that if I place <code>print</code> after <code>take</code>, I will print two filterred and inced values, 4 and 6:</p>
<p>Let&rsquo;s check. Define <code>a</code>: it takes value a, prints it and returns it.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-clojure">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-clojure" data-lang="clojure"><span class="line"><span class="cl"><span class="nv">user&gt;</span> <span class="p">(</span><span class="kd">defn </span> <span class="nv">a</span> <span class="p">[</span><span class="nv">a</span><span class="p">]</span> <span class="p">(</span><span class="nb">println </span><span class="s">&#34;* &#34;</span> <span class="nv">a</span> <span class="s">&#34; *&#34;</span><span class="p">)</span> <span class="nv">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="o">#</span><span class="ss">&#39;user/a</span>
</span></span><span class="line"><span class="cl"><span class="nv">user&gt;</span> <span class="p">(</span><span class="nb">map </span><span class="nv">a</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">50</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">* </span> <span class="mi">1</span>  <span class="nv">*</span>
</span></span><span class="line"><span class="cl"><span class="nb">* </span> <span class="mi">2</span>  <span class="nv">*</span>
</span></span><span class="line"><span class="cl"><span class="nb">* </span> <span class="mi">50</span>  <span class="nv">*</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">50</span><span class="p">)</span></span></span></code></pre></div></div>
<p>Transducer <code>xf</code> now is composed of <code>(map a)</code> as first element of the pipeline. Wow, see what happened: it not only <em>did not</em> call map on each element of the sequence - it only executec exectly 3 times - minimal number of times needed to actually retrieve two elements required by last element of the pipeline&hellip;:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-clojure">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-clojure" data-lang="clojure"><span class="line"><span class="cl"><span class="nv">user&gt;</span> <span class="p">(</span><span class="k">def </span><span class="nv">xf</span> <span class="p">(</span><span class="nb">comp </span><span class="p">(</span><span class="nb">map </span><span class="nv">a</span><span class="p">)</span> <span class="p">(</span><span class="nb">filter </span><span class="nv">odd?</span><span class="p">)</span> <span class="p">(</span><span class="nb">map </span><span class="nv">inc</span><span class="p">)</span> <span class="p">(</span><span class="nb">take </span><span class="mi">2</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl"><span class="o">#</span><span class="ss">&#39;user/xf</span>
</span></span><span class="line"><span class="cl"><span class="nv">user&gt;</span> <span class="p">(</span><span class="nf">transduce</span> <span class="nv">xf</span> <span class="nb">+ </span><span class="p">[</span><span class="mi">3</span>,<span class="mi">4</span>,<span class="mi">5</span>,<span class="mi">6</span>,<span class="mi">7</span>,<span class="mi">8</span>,<span class="mi">9</span>,<span class="mi">10</span>,<span class="mi">11</span>,<span class="mi">12</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="nb">* </span> <span class="mi">3</span>  <span class="nv">*</span>
</span></span><span class="line"><span class="cl"><span class="nb">* </span> <span class="mi">4</span>  <span class="nv">*</span>
</span></span><span class="line"><span class="cl"><span class="nb">* </span> <span class="mi">5</span>  <span class="nv">*</span>
</span></span><span class="line"><span class="cl"><span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="nv">user&gt;</span> </span></span></code></pre></div></div>
<p>Interesting.</p>
<h2 id="in-rust">In Rust</h2>
<p>This behavior is similar to what we get in Rust - there are iterators everywhere :)
For example, below program constructs an infinite collection (wait! it is iterator!) and traverses it:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-rust">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">result</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mi">0</span><span class="k">u64</span><span class="o">..</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">.</span><span class="n">filter</span><span class="p">(</span><span class="o">|</span><span class="n">n</span><span class="o">|</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">n</span><span class="o">|</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">.</span><span class="n">take_while</span><span class="p">(</span><span class="o">|&amp;</span><span class="n">n</span><span class="o">|</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">1_000_000</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">.</span><span class="n">filter</span><span class="p">(</span><span class="o">|</span><span class="n">n</span><span class="o">|</span><span class="w"> </span><span class="n">n</span><span class="p">.</span><span class="n">to_string</span><span class="p">().</span><span class="n">starts_with</span><span class="p">(</span><span class="sc">&#39;4&#39;</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">n</span><span class="o">|</span><span class="w"> </span><span class="fm">format!</span><span class="p">(</span><span class="s">&#34;val:</span><span class="si">{n}</span><span class="s">&#34;</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">.</span><span class="n">collect</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// The entire chain runs element-by-element — no intermediate Vec
</span></span></span></code></pre></div></div>
<p>So the example with simple collection will be as follows:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-rust">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">report_double</span><span class="p">(</span><span class="n">v</span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span> <span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">doubled</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;Reporting </span><span class="si">{}</span><span class="s"> -&gt; </span><span class="si">{}</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">,</span><span class="w"> </span><span class="n">doubled</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">doubled</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">simple_pipeline</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="mi">34</span><span class="p">,</span><span class="w"> </span><span class="mi">78</span><span class="p">,</span><span class="w"> </span><span class="mi">126</span><span class="p">];</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">v</span><span class="p">.</span><span class="n">iter</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">n</span><span class="o">|</span><span class="w"> </span><span class="n">report_double</span><span class="p">(</span><span class="o">*</span><span class="n">n</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="n">filter</span><span class="p">(</span><span class="o">|</span><span class="n">v</span><span class="o">|</span><span class="w"> </span><span class="o">*</span><span class="n">v</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">20</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="n">take</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="n">collect</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;Example pipeline: </span><span class="si">{:#?}</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">simple_pipeline</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>which behaves nicely - does not go through whole collection and gives exactly what I expected = three elements:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Reporting 1 -&gt; 2
</span></span><span class="line"><span class="cl">Reporting 2 -&gt; 4
</span></span><span class="line"><span class="cl">Reporting 5 -&gt; 10
</span></span><span class="line"><span class="cl">Example pipeline: [
</span></span><span class="line"><span class="cl">    2,
</span></span><span class="line"><span class="cl">    4,
</span></span><span class="line"><span class="cl">    10,
</span></span><span class="line"><span class="cl">]</span></span></code></pre></div></div>
<p>Making the pipeline more generic can be done by making collection&rsquo;s element generic or by creating a function that takes an <code>Iterator&lt;Item=i32&gt;</code> - which allows to use the <code>pipeline</code> on both vec and set (note non-deteministic output):</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-rust">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">pipeline</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nb">Iterator</span><span class="o">&lt;</span><span class="n">Item</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">i32</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">it</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">it</span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">n</span><span class="o">|</span><span class="w"> </span><span class="n">report_double</span><span class="p">(</span><span class="n">n</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="n">filter</span><span class="p">(</span><span class="o">|</span><span class="n">v</span><span class="o">|</span><span class="w"> </span><span class="o">*</span><span class="n">v</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">20</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="n">take</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">.</span><span class="n">collect</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;Print pipeline:&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;</span><span class="si">{:#?}</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">pipeline</span><span class="p">(</span><span class="fm">vec!</span><span class="p">[</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="w"> </span><span class="mi">200</span><span class="p">].</span><span class="n">into_iter</span><span class="p">()));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="s">&#34;</span><span class="si">{:#?}</span><span class="s">&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">pipeline</span><span class="p">(</span><span class="n">HashSet</span>::<span class="n">from</span><span class="p">([</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="w"> </span><span class="mi">200</span><span class="p">]).</span><span class="n">into_iter</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>or by also returning an iterator - in this case I need to force collection (note a call to <code>.collect::&lt;Vec&lt;i32&gt;&gt;()</code>)to be able to print the results as iterator itself does not implement <code>Display</code>:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-rust">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">pipeline</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nb">Iterator</span><span class="o">&lt;</span><span class="n">Item</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">i32</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">it</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">impl</span><span class="w"> </span><span class="nb">Iterator</span><span class="o">&lt;</span><span class="n">Item</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">i32</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">it</span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">n</span><span class="o">|</span><span class="w"> </span><span class="n">report_double</span><span class="p">(</span><span class="n">n</span><span class="p">)).</span><span class="n">filter</span><span class="p">(</span><span class="o">|</span><span class="n">v</span><span class="o">|</span><span class="w"> </span><span class="o">*</span><span class="n">v</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">20</span><span class="p">).</span><span class="n">take</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;Print pipeline:&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="s">&#34;</span><span class="si">{:#?}</span><span class="s">&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">pipeline</span><span class="p">(</span><span class="fm">vec!</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="w"> </span><span class="mi">200</span><span class="p">].</span><span class="n">into_iter</span><span class="p">()).</span><span class="n">collect</span>::<span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;&gt;</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="s">&#34;</span><span class="si">{:#?}</span><span class="s">&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">pipeline</span><span class="p">(</span><span class="n">HashSet</span>::<span class="n">from</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="w"> </span><span class="mi">200</span><span class="p">]).</span><span class="n">into_iter</span><span class="p">()).</span><span class="n">collect</span>::<span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;&gt;</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>which gives following output (obviously, duplicates disappeared on HashSet construction, and set output changes in each execution of the program):</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"> Print pipeline:
</span></span><span class="line"><span class="cl">Reporting 1 -&gt; 2
</span></span><span class="line"><span class="cl">Reporting 1 -&gt; 2
</span></span><span class="line"><span class="cl">Reporting 3 -&gt; 6
</span></span><span class="line"><span class="cl">[
</span></span><span class="line"><span class="cl">    2,
</span></span><span class="line"><span class="cl">    2,
</span></span><span class="line"><span class="cl">    6,
</span></span><span class="line"><span class="cl">]
</span></span><span class="line"><span class="cl">Reporting 4 -&gt; 8
</span></span><span class="line"><span class="cl">Reporting 200 -&gt; 400
</span></span><span class="line"><span class="cl">Reporting 100 -&gt; 200
</span></span><span class="line"><span class="cl">Reporting 1 -&gt; 2
</span></span><span class="line"><span class="cl">Reporting 3 -&gt; 6
</span></span><span class="line"><span class="cl">[
</span></span><span class="line"><span class="cl">    8,
</span></span><span class="line"><span class="cl">    2,
</span></span><span class="line"><span class="cl">    6,
</span></span><span class="line"><span class="cl">]</span></span></code></pre></div></div>
<h1 id="conclusions">Conclusions</h1>
<p>Let&rsquo;s go back to initial question: can I define a pipeline once, keep it lazy and reuse with different inputs?</p>
<p>This question has two separate parts: laziness and reusability, and different languages answer them in a different way.</p>
<p><em>Python</em> is lazy: <code>map</code> and <code>filter</code> return iterators which are evaluated <em>lazily</em> element-by-element when they are consumed (in terminal operations, like creating a <code>list()</code>), and those iterators are <em>single use</em>: when exhaused, cannot be re-run. To re-use, you can define a function; to short-cirquit, you can use <code>itertools.islice</code>.</p>
<p><em>Scala</em> defaults to <em>strict evaluation</em> - every <code>map</code> and <code>filter</code> on a List creates a full intermediate collection. You can opt-out using <code>.view</code> which <em>defers</em> all operations until a terminal <code>foreach</code> which will process what&rsquo;s needed. <code>view</code>-based pipeline can be reused: it holds reference to original collection, and rebuilds the lazy chain on each terminal call - but it needs to be a single expression! (Confusing part: if you assign intermedite result to a <code>val</code> it will force evaluation at that point and break laziness.)</p>
<p><em>Rust</em> makes laziness default - iterators cause evaluation elem-by-elem, there is no intermediate collections created, and those pipelines short-cirquit nicely with <code>take</code> or <code>take while</code>. If you define a pipeline inside a function that takes <code>impl Iterator</code>, it is (somewhat) independent from the input: you can pass vec, set, infinite range. Very elegant.</p>
<p><em>Clojure</em> has a concept of a transducer - it is a pipeline definition that is completely decoupled from the source <em>and</em> the collection of results: you define complex transducers by combining simpler transducers using <code>comp</code> and then uou can appply it to different sinks (<code>transduce</code>, <code>into</code>) It evaluates lazily and minimally - only as many elements are processed as needed. Of all four langiuages I experimender with, transducers in Clojure are closest to my idea of an independent pipeline.</p>
<p>Depending on what you need, you can choose what you want! What I needed for sure was the above journey - it let me  to order the concept of pipelined computations in my head. Jumping bewteen languages and using all of them at the same time sometimes casues the concepts leak between areas of my brain, causing a bit of confusion :D</p>
<p>Happy hacking!</p>
]]></description>
</item>
<item>
    <title>Some exercism and kata</title>
    <link>/posts/2026-04-01_exercism_et_al/</link>
    <pubDate>Wed, 01 Apr 2026 12:08:00 &#43;0200</pubDate>
    <author>Kamila Chyla</author>
    <guid>/posts/2026-04-01_exercism_et_al/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/image.jpg" referrerpolicy="no-referrer">
            </div><ol>
<li>Exercism
Completed Phase 1 week 3 exercises on <a href="https://exercism.org/profiles/kamchy" target="_blank" rel="noopener noreffer ">exercism</a>:
<ol>
<li>hello-world</li>
<li>two-fer</li>
<li>raindrops</li>
<li>bob</li>
<li>hamming</li>
<li>pangram</li>
<li>isogram</li>
<li>difference-of-squares</li>
</ol>
</li>
</ol>
<p></p>
<ol start="2">
<li>Played with function composition in scala - implemented simple banner generator (see header of this and previous entry).</li>
</ol>
<p>Also, learned about external process calling</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl">  <span class="k">object</span> <span class="nc">Colors</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">abstract</span> <span class="k">class</span> <span class="nc">ColorSource</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">      <span class="c1">//generate colors from string once
</span></span></span><span class="line"><span class="cl">      <span class="k">lazy</span> <span class="k">val</span> <span class="n">into</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Color</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">val</span> <span class="n">hx</span> <span class="k">=</span> <span class="n">hexes</span><span class="o">()</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="o">(</span><span class="n">hx</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">hx</span><span class="o">.</span><span class="n">map</span><span class="o">(</span><span class="nc">Color</span><span class="o">.</span><span class="n">decode</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">      <span class="o">}</span>
</span></span><span class="line"><span class="cl">      <span class="k">def</span> <span class="n">hexes</span><span class="o">()</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">      <span class="k">def</span> <span class="n">random</span><span class="k">:</span> <span class="kt">Color</span> <span class="o">=</span> <span class="n">into</span><span class="o">(</span><span class="n">r</span><span class="o">.</span><span class="n">nextInt</span><span class="o">(</span><span class="n">into</span><span class="o">.</span><span class="n">length</span><span class="o">))</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">class</span> <span class="nc">Pastel</span> <span class="k">extends</span> <span class="nc">ColorSource</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">def</span> <span class="n">hexes</span><span class="o">()</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">import</span> <span class="nn">scala.sys.process._</span>
</span></span><span class="line"><span class="cl">        <span class="k">val</span> <span class="n">result</span> <span class="k">=</span> <span class="o">(</span><span class="nc">Seq</span><span class="o">(</span><span class="s">&#34;pastel&#34;</span><span class="o">,</span> <span class="s">&#34;random&#34;</span><span class="o">,</span><span class="s">&#34;-s&#34;</span><span class="o">,</span>  <span class="s">&#34;vivid&#34;</span><span class="o">)</span> <span class="o">#|</span> <span class="nc">Seq</span><span class="o">(</span><span class="s">&#34;pastel&#34;</span><span class="o">,</span> <span class="s">&#34;format&#34;</span><span class="o">,</span> <span class="s">&#34;hex&#34;</span><span class="o">)).!!</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span><span class="o">.</span><span class="n">split</span><span class="o">(</span><span class="s">&#34;\n&#34;</span><span class="o">).</span><span class="n">toList</span>
</span></span><span class="line"><span class="cl">      <span class="o">}</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">class</span> <span class="nc">Gradient</span><span class="o">(</span><span class="n">from</span><span class="k">:</span> <span class="kt">String</span><span class="o">=</span><span class="s">&#34;ffffcc&#34;</span><span class="o">,</span> <span class="n">to</span><span class="k">:</span> <span class="kt">String</span><span class="o">=</span><span class="s">&#34;fd8d3c&#34;</span><span class="o">,</span> <span class="n">n</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">5</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">ColorSource</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">def</span> <span class="n">hexes</span><span class="o">()</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">import</span> <span class="nn">scala.sys.process._</span>
</span></span><span class="line"><span class="cl">        <span class="k">val</span> <span class="n">cmd</span> <span class="k">=</span> <span class="nc">Seq</span><span class="o">(</span><span class="s">&#34;pastel&#34;</span><span class="o">,</span> <span class="s">&#34;gradient&#34;</span><span class="o">,</span> <span class="s">&#34;--colorspace&#34;</span><span class="o">,</span> <span class="s">&#34;HSL&#34;</span><span class="o">,</span> <span class="n">from</span><span class="o">,</span> <span class="n">to</span><span class="o">,</span> <span class="s">&#34;-n&#34;</span><span class="o">,</span> <span class="n">n</span><span class="o">.</span><span class="n">toString</span><span class="o">)</span> <span class="o">#|</span> <span class="nc">Seq</span><span class="o">(</span><span class="s">&#34;pastel&#34;</span><span class="o">,</span> <span class="s">&#34;format&#34;</span><span class="o">,</span> <span class="s">&#34;hex&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="o">(</span><span class="n">cmd</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">val</span> <span class="n">result</span> <span class="k">=</span> <span class="n">cmd</span><span class="o">.!!</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span><span class="o">.</span><span class="n">split</span><span class="o">(</span><span class="s">&#34;\n&#34;</span><span class="o">).</span><span class="n">toList</span>
</span></span><span class="line"><span class="cl">      <span class="o">}</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">class</span> <span class="nc">Fixed</span><span class="o">(</span><span class="n">cols</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span> <span class="k">extends</span> <span class="nc">ColorSource</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">def</span> <span class="n">hexes</span><span class="o">()</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">]</span> <span class="k">=</span> <span class="n">cols</span>              
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="n">pastel</span><span class="k">:</span> <span class="kt">ColorSource</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Pastel</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="n">gradient</span><span class="o">(</span><span class="n">from</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="n">to</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="n">n</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">Gradient</span><span class="o">(</span><span class="n">from</span><span class="o">,</span> <span class="n">to</span><span class="o">,</span> <span class="n">n</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="n">fixed</span><span class="o">(</span><span class="n">cols</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">Fixed</span><span class="o">(</span><span class="n">cols</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">	
</span></span><span class="line"><span class="cl">	<span class="cm">/** ... */</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span></span></span></code></pre></div></div>
<ol start="3">
<li>Setting up rustlings failed. I probably messed up the configuration (or had old version of <code>rustlings</code> tool). Worked after removal of whole repo (minus execrises done so far),tool reinstall (<code>cargo install rustlings</code>), <code>rustlings init</code> and copying over my exercises.</li>
</ol>
<p></p>
<ol start="4">
<li>Learned  about traits from <a href="https://doc.rust-lang.org/book/ch10-02-traits.html" target="_blank" rel="noopener noreffer ">https://doc.rust-lang.org/book/ch10-02-traits.html</a></li>
</ol>
]]></description>
</item>
<item>
    <title>Discover duplicated files</title>
    <link>/posts/2026-03-29_duplicate_files_detection/</link>
    <pubDate>Sun, 29 Mar 2026 13:31:12 &#43;0200</pubDate>
    <author>Kamila Chyla</author>
    <guid>/posts/2026-03-29_duplicate_files_detection/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/image.png" referrerpolicy="no-referrer">
            </div><h1 id="problem">Problem</h1>
<p>I have a directory where I store files: articles, images, notes - in a bit unordered and random fashion: I copy them from other devices, generate some files requried for teaching sessions or create subdirectrories for experimentation.</p>
<p>As a result, this directory is messy and contains a lot of duplicated files. Some of them are quite big (think: .epub or .pdf, not linux distro .iso).</p>
<p>So, I thought, this is a good candiate for a practical problem solving exercise joined with language learning practice for Rust and Scala.</p>
<p>The idea is simple: I will scan the directory recursively and for each file I will calculate the SHA-256 sum and put the sum and path to a hash map, printing those sums for which there is more than one path entry.</p>
<h1 id="experiment">Experiment</h1>
<p>I decided to write this in scala and in rust.</p>
<h1 id="results">Results</h1>
<p>In Scala I use following case class representing a path with its sha sum:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">case</span> <span class="k">class</span> <span class="nc">ShaRes</span><span class="o">(</span><span class="k">val</span> <span class="n">sha</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="n">p</span><span class="k">:</span> <span class="kt">os.Path</span><span class="o">)</span></span></span></code></pre></div></div>
<h2 id="scala-with-external-process-called-per-file">Scala with external process called per file</h2>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">private</span> <span class="k">def</span> <span class="n">usingExternal</span><span class="o">(</span><span class="n">p</span><span class="k">:</span> <span class="kt">os.Path</span><span class="o">)</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">ShaRes</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span> 
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="n">res</span><span class="k">:</span> <span class="kt">os.CommandResult</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">proc</span><span class="o">(</span><span class="s">&#34;shasum&#34;</span><span class="o">,</span> <span class="s">&#34;-a&#34;</span><span class="o">,</span> <span class="s">&#34;256&#34;</span><span class="o">,</span> <span class="n">p</span><span class="o">.</span><span class="n">toString</span><span class="o">).</span><span class="n">call</span><span class="o">()</span>
</span></span><span class="line"><span class="cl">    <span class="nc">List</span><span class="o">(</span><span class="n">res</span><span class="o">.</span><span class="n">out</span><span class="o">.</span><span class="n">text</span><span class="o">().</span><span class="n">split</span><span class="o">(</span><span class="s">&#34;\\s+&#34;</span><span class="o">)</span> <span class="o">*)</span> <span class="k">match</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">case</span> <span class="n">md</span> <span class="k">:</span><span class="kt">:</span> <span class="kt">rest</span> <span class="o">=&gt;</span> <span class="nc">Some</span><span class="o">(</span><span class="nc">ShaRes</span><span class="o">(</span><span class="n">md</span><span class="o">,</span> <span class="n">p</span><span class="o">))</span>
</span></span><span class="line"><span class="cl">      <span class="k">case</span> <span class="n">v</span> <span class="k">=&gt;</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="o">(</span><span class="nc">Cons</span><span class="o">.</span><span class="n">err</span><span class="o">(</span><span class="s">s&#34;Could not parse </span><span class="si">$p</span><span class="s">&#34;</span><span class="o">))</span>
</span></span><span class="line"><span class="cl">        <span class="nc">None</span>
</span></span><span class="line"><span class="cl">      <span class="o">}</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span></span></span></code></pre></div></div>
<p>I build scala with:
<code>scala-cli --power package Main.scala -o books</code>
and run it with
<code>time ./books  /home/karma/Dokumenty/books/</code></p>
<p>Scala with external process call for each file:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">real    0m36,687s
</span></span><span class="line"><span class="cl">user    0m35,232s
</span></span><span class="line"><span class="cl">sys     0m4,635s</span></span></code></pre></div></div>
<h2 id="scala-using-messagedigest">Scala using <code>MessageDigest</code>:</h2>
<p>Here the path is passed to MessageDigets&rsquo; <code>update</code> method:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">private</span> <span class="k">def</span> <span class="n">usingDigest</span><span class="o">(</span><span class="n">p</span><span class="k">:</span> <span class="kt">os.Path</span><span class="o">)</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">ShaRes</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">import</span> <span class="nn">java.nio.file.Files</span>
</span></span><span class="line"><span class="cl">    <span class="k">import</span> <span class="nn">java.security.MessageDigest</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">	<span class="k">val</span> <span class="n">md</span> <span class="k">=</span> <span class="nc">MessageDigest</span><span class="o">.</span><span class="n">getInstance</span><span class="o">(</span><span class="s">&#34;SHA-256&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">md</span><span class="o">.</span><span class="n">update</span><span class="o">(</span><span class="nc">Files</span><span class="o">.</span><span class="n">readAllBytes</span><span class="o">(</span><span class="n">p</span><span class="o">.</span><span class="n">wrapped</span><span class="o">))</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="n">sha</span> <span class="k">=</span> <span class="n">md</span><span class="o">.</span><span class="n">digest</span><span class="o">().</span><span class="n">map</span><span class="o">(</span><span class="n">b</span> <span class="k">=&gt;</span> <span class="s">f&#34;</span><span class="si">$b</span><span class="s">%02x&#34;</span><span class="o">).</span><span class="n">mkString</span>
</span></span><span class="line"><span class="cl">    <span class="nc">Some</span><span class="o">(</span><span class="nc">ShaRes</span><span class="o">(</span><span class="n">sha</span><span class="o">,</span> <span class="n">p</span><span class="o">))</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span></span></span></code></pre></div></div>
<p>Result:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">real    0m5,642s
</span></span><span class="line"><span class="cl">user    0m5,899s
</span></span><span class="line"><span class="cl">sys     0m1,136s</span></span></code></pre></div></div>
<h2 id="rust">Rust</h2>
<p>Sha calculation uses sha2 crate:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-rust">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">sha_read</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Read</span><span class="o">&gt;</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">r</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">io</span>::<span class="nb">Result</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">sha256</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Sha256</span>::<span class="n">new</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">io</span>::<span class="n">copy</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">r</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">sha256</span><span class="p">)</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">hash</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sha256</span><span class="p">.</span><span class="n">finalize</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">format!</span><span class="p">(</span><span class="s">&#34;</span><span class="si">{:x}</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">hash</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">.</span><span class="n">to_string</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">sha</span><span class="p">(</span><span class="n">fname</span>: <span class="kp">&amp;</span><span class="kt">str</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">io</span>::<span class="nb">Result</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">File</span>::<span class="n">open</span><span class="p">(</span><span class="n">fname</span><span class="p">)</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">sha_read</span><span class="p">(</span><span class="n">file</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>and iterates over directory entries using walkdir crate.
ShaStore datastructure aims to mimic hashmap approach from scala:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-rust">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="cp">#[derive(Debug)]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">struct</span> <span class="nc">ShaStore</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">shas</span>: <span class="nc">HashMap</span><span class="o">&lt;</span><span class="nb">String</span><span class="p">,</span><span class="w"> </span><span class="nb">Vec</span><span class="o">&lt;&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="n">Path</span><span class="o">&gt;&gt;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">errors</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">impl</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="n">ShaStore</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">fn</span> <span class="nf">new</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">ShaStore</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">shas</span>: <span class="nc">HashMap</span>::<span class="n">new</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">errors</span>: <span class="nb">Vec</span>::<span class="n">new</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">fn</span> <span class="nf">update</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">pref</span>: <span class="kp">&amp;</span><span class="na">&#39;a</span> <span class="nc">Path</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">io</span>::<span class="nb">Result</span><span class="o">&lt;</span><span class="p">()</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">shares</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pref</span><span class="p">.</span><span class="n">to_str</span><span class="p">().</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">p</span><span class="o">|</span><span class="w"> </span><span class="n">sha</span><span class="p">(</span><span class="n">p</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">match</span><span class="w"> </span><span class="n">shares</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nb">Some</span><span class="p">(</span><span class="nb">Ok</span><span class="p">(</span><span class="n">shaval</span><span class="p">))</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">v</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">shas</span><span class="p">.</span><span class="n">get_mut</span><span class="p">(</span><span class="o">&amp;</span><span class="n">shaval</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">v</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">pref</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="bp">self</span><span class="p">.</span><span class="n">shas</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">shaval</span><span class="p">.</span><span class="n">clone</span><span class="p">(),</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[</span><span class="n">pref</span><span class="p">]);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nb">Some</span><span class="p">(</span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">))</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="bp">self</span><span class="p">.</span><span class="n">errors</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">e</span><span class="p">.</span><span class="n">to_string</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">errors</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="s">&#34;No sha&#34;</span><span class="p">.</span><span class="n">to_string</span><span class="p">()),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nb">Ok</span><span class="p">(())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Rust with calculation:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">real    0m4,796s
</span></span><span class="line"><span class="cl">user    0m3,846s
</span></span><span class="line"><span class="cl">sys     0m0,704s</span></span></code></pre></div></div>
<h2 id="first-conclusion">First conclusion</h2>
<p>Calling a subprocess and wait synchronously is a huge overkill. It seems that digest calculation in-process is really very fast - the difference between scala and rust is not very significant. Well, most of the time we&rsquo;re just accessing filesystem and calculating sha.</p>
<ul>
<li>individual sha calculations are independent and can be done in parallel</li>
<li>what datastructure in Scala is safe for concurrent acces?</li>
<li>in scala I can try to spawn a <code>Future</code>; in Rust I could
Well, perhaps it is a good moment to try and introuduce some concurrency?</li>
</ul>
]]></description>
</item>
<item>
    <title>So what Options do I have?</title>
    <link>/posts/2026-03-17_so_what_options_do_i_have/</link>
    <pubDate>Tue, 17 Mar 2026 13:20:32 &#43;0100</pubDate>
    <author>Kamila Chyla</author>
    <guid>/posts/2026-03-17_so_what_options_do_i_have/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/new.jpg" referrerpolicy="no-referrer">
            </div><h1 id="option-types">Option types</h1>
<p>Option type documentation:</p>
<ul>
<li><a href="https://www.scala-lang.org/api/current/scala/Option.html" target="_blank" rel="noopener noreffer ">Scala Option</a></li>
<li><a href="https://doc.rust-lang.org/std/option/index.html" target="_blank" rel="noopener noreffer ">Rust Option</a></li>
</ul>
<h2 id="same-names-a-bit-different-api">Same names, a bit different API</h2>
<h3 id="scala">Scala</h3>
<p>In Scala the variants are called: <a href="https://www.scala-lang.org/api/current/scala/None$.html" target="_blank" rel="noopener noreffer ">None</a> and <a href="https://www.scala-lang.org/api/current/scala/Some.html" target="_blank" rel="noopener noreffer ">Some</a>
which are final case subclasses of Option. I&rsquo;ve noticed the subclassing has the nice property of helping in IDE to discover the variants (which is also the case, for example, for <a href="https://www.scala-lang.org/api/current/scala/util/Try.html" target="_blank" rel="noopener noreffer ">Try</a> subclasses.</p>
<h3 id="rust">Rust</h3>
<p>In Rust, the variants are also conveniently named <a href="https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some" target="_blank" rel="noopener noreffer ">Some</a> and <a href="https://doc.rust-lang.org/std/option/enum.Option.html#variant.None" target="_blank" rel="noopener noreffer ">None</a>.</p>
<h3 id="api-differences">API differences</h3>
<p>(Scala vs Rust)</p>
<ul>
<li>check presence:    isDefined       vs  is_some</li>
<li>check absence:     isEmpty         vs  is_none</li>
<li>transform value:   map             vs  map</li>
<li>chain options:     flatMap         vs  and_then</li>
<li>filter value:      filter          vs  filter</li>
<li>default value:     getOrElse       vs  unwrap_or</li>
<li>lazy default:      getOrElse       vs  unwrap_or_else</li>
<li>alternative:      orElse:           vs  or</li>
<li>to collection:     toList          vs  iter</li>
<li>unsafe extract:    get             vs  unwrap</li>
</ul>
<h3 id="some-specifics">Some specifics</h3>
<ul>
<li>Scala has some functions that
<ul>
<li><a href="https://www.scala-lang.org/api/current/scala/Option.html#orNull-e58" target="_blank" rel="noopener noreffer ">does not make sense in Rust</a> but has when interop with Java is required (orNull - Rust has no null by design)</li>
<li>convert to <a href="https://www.scala-lang.org/api/current/scala/util/Either.html" target="_blank" rel="noopener noreffer ">Either</a> subtypes (toLeft, toRight)</li>
</ul>
</li>
<li>Rust has functions
<ul>
<li>to <a href="https://doc.rust-lang.org/std/option/index.html#adapters-for-working-with-references" target="_blank" rel="noopener noreffer ">convert between reference types</a> (as_ref, as_mut, as_deref)</li>
<li>to <a href="https://doc.rust-lang.org/std/option/index.html#adapters-for-working-with-references" target="_blank" rel="noopener noreffer ">modify in place or work with ownership</a> (take, replace)</li>
<li>to <a href="https://doc.rust-lang.org/std/option/index.html#transforming-contained-values" target="_blank" rel="noopener noreffer ">transform to Result</a> (ok_or, transpose)</li>
</ul>
</li>
</ul>
<h1 id="exercise-1---compare-rust-and-scala">Exercise 1 - compare Rust and Scala</h1>
<p>This is the example from Rust module option docs:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-rust">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">enum</span> <span class="nc">Kingdom</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">Plant</span><span class="p">(</span><span class="kt">u32</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="nb">&#39;static</span><span class="w"> </span><span class="kt">str</span><span class="p">),</span><span class="w"> </span><span class="n">Animal</span><span class="p">(</span><span class="kt">u32</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="nb">&#39;static</span><span class="w"> </span><span class="kt">str</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// A list of data to search through.
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">all_the_big_things</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Kingdom</span>::<span class="n">Plant</span><span class="p">(</span><span class="mi">250</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;redwood&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Kingdom</span>::<span class="n">Plant</span><span class="p">(</span><span class="mi">230</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;noble fir&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Kingdom</span>::<span class="n">Plant</span><span class="p">(</span><span class="mi">229</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;sugar pine&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Kingdom</span>::<span class="n">Animal</span><span class="p">(</span><span class="mi">25</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;blue whale&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Kingdom</span>::<span class="n">Animal</span><span class="p">(</span><span class="mi">19</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;fin whale&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Kingdom</span>::<span class="n">Animal</span><span class="p">(</span><span class="mi">15</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;north pacific right whale&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">];</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// We&#39;re going to search for the name of the biggest animal,
</span></span></span><span class="line"><span class="cl"><span class="c1">// but to start with we&#39;ve just got `None`.
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">name_of_biggest_animal</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">None</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">size_of_biggest_animal</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="n">big_thing</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="o">&amp;</span><span class="n">all_the_big_things</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="o">*</span><span class="n">big_thing</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Kingdom</span>::<span class="n">Animal</span><span class="p">(</span><span class="n">size</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="p">)</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">size_of_biggest_animal</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="c1">// Now we&#39;ve found the name of some big animal
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">size_of_biggest_animal</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">size</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">name_of_biggest_animal</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">name</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Kingdom</span>::<span class="n">Animal</span><span class="p">(</span><span class="o">..</span><span class="p">)</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Kingdom</span>::<span class="n">Plant</span><span class="p">(</span><span class="o">..</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">match</span><span class="w"> </span><span class="n">name_of_biggest_animal</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">name</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;the biggest animal is </span><span class="si">{name}</span><span class="s">&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;there are no animals :(&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Let&rsquo;s see how it would look like in scala:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">private</span> <span class="k">object</span> <span class="nc">Kingdom</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">final</span> <span class="k">case</span> <span class="k">class</span> <span class="nc">Plant</span><span class="o">(</span><span class="n">age</span><span class="k">:</span> <span class="kt">Int</span><span class="o">,</span> <span class="n">name</span><span class="k">:</span> <span class="kt">String</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">final</span> <span class="k">case</span> <span class="k">class</span> <span class="nc">Animal</span><span class="o">(</span><span class="n">age</span><span class="k">:</span> <span class="kt">Int</span><span class="o">,</span> <span class="n">name</span><span class="k">:</span> <span class="kt">String</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">private</span> <span class="k">val</span> <span class="n">allTheBigThings</span> <span class="k">=</span> <span class="nc">Vector</span><span class="o">(</span>
</span></span><span class="line"><span class="cl">    <span class="nc">Kingdom</span><span class="o">.</span><span class="nc">Plant</span><span class="o">(</span><span class="mi">250</span><span class="o">,</span> <span class="s">&#34;redwood&#34;</span><span class="o">),</span>
</span></span><span class="line"><span class="cl">    <span class="nc">Kingdom</span><span class="o">.</span><span class="nc">Plant</span><span class="o">(</span><span class="mi">230</span><span class="o">,</span> <span class="s">&#34;noble fir&#34;</span><span class="o">),</span>
</span></span><span class="line"><span class="cl">    <span class="nc">Kingdom</span><span class="o">.</span><span class="nc">Plant</span><span class="o">(</span><span class="mi">229</span><span class="o">,</span> <span class="s">&#34;sugar pine&#34;</span><span class="o">),</span>
</span></span><span class="line"><span class="cl">    <span class="nc">Kingdom</span><span class="o">.</span><span class="nc">Animal</span><span class="o">(</span><span class="mi">25</span><span class="o">,</span> <span class="s">&#34;blue whale&#34;</span><span class="o">),</span>
</span></span><span class="line"><span class="cl">    <span class="nc">Kingdom</span><span class="o">.</span><span class="nc">Animal</span><span class="o">(</span><span class="mi">19</span><span class="o">,</span> <span class="s">&#34;fin whale&#34;</span><span class="o">),</span>
</span></span><span class="line"><span class="cl">    <span class="nc">Kingdom</span><span class="o">.</span><span class="nc">Animal</span><span class="o">(</span><span class="mi">15</span><span class="o">,</span> <span class="s">&#34;north pacific right whale&#34;</span><span class="o">),</span>
</span></span><span class="line"><span class="cl">  <span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">private</span> <span class="k">def</span> <span class="n">findBiggest</span><span class="o">()</span><span class="k">:</span> <span class="kt">Unit</span> <span class="o">=</span>  <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">var</span> <span class="n">nameOfTheBiggestAnimal</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">String</span><span class="o">]</span> <span class="k">=</span> <span class="nc">None</span>
</span></span><span class="line"><span class="cl">    <span class="k">var</span> <span class="n">sizeOfTheBiggestAnimal</span> <span class="k">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="n">allTheBigThings</span><span class="o">.</span><span class="n">foreach</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">case</span> <span class="nc">Kingdom</span><span class="o">.</span><span class="nc">Animal</span><span class="o">(</span><span class="n">age</span><span class="o">,</span> <span class="n">name</span><span class="o">)</span> <span class="k">if</span> <span class="n">age</span> <span class="o">&gt;</span> <span class="n">sizeOfTheBiggestAnimal</span> <span class="k">=&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="n">sizeOfTheBiggestAnimal</span> <span class="k">=</span> <span class="n">age</span>
</span></span><span class="line"><span class="cl">        <span class="n">nameOfTheBiggestAnimal</span> <span class="k">=</span> <span class="nc">Some</span><span class="o">(</span><span class="n">name</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">      <span class="k">case</span> <span class="k">_</span> <span class="k">=&gt;</span> <span class="o">()</span>
</span></span><span class="line"><span class="cl">      <span class="c1">// or:
</span></span></span><span class="line"><span class="cl">      <span class="c1">// case Kingdom.Animal(_,_) | Kingdom.Plant(_,_) =&gt; ()
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">nameOfTheBiggestAnimal</span> <span class="k">match</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">case</span> <span class="nc">Some</span><span class="o">(</span><span class="n">name</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">println</span><span class="o">(</span><span class="s">s&#34;the bigest animal is </span><span class="si">$name</span><span class="s">&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">      <span class="k">case</span> <span class="nc">None</span> <span class="k">=&gt;</span> <span class="n">println</span><span class="o">(</span><span class="s">&#34;There are no animals :(&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span></span></span></code></pre></div></div>
<p>My notes:</p>
<ul>
<li>in scala 2.x (before enum and named tuples) modelling two similar variants is possible either by
<ul>
<li>overriding <code>abstract class Kingdom</code> in case subclasses (would preserve class hierarchy) or</li>
<li>scoping <code>case class Plant</code> and <code>case class Animal</code> in <code>object Kingdom</code> which allows, well, scope access (which I like very much - this approach pushes towards providing explicit path to a class)</li>
</ul>
</li>
<li>forEach allows to pattern match in anonymous function - without defining any binding to a iteration variable (big_thing in Rust snippet)</li>
<li>scala requires to declare a type of <code>nameOfTheBiggestAnimal</code> - without it the code does not compile; that&rsquo;s because <code>None</code> value resolves to <code>None.type</code> and Some[String] is expected in assignment: compiler cries until I fixed that:</li>
</ul>
<p>
</p>
<h1 id="exercise-2---rewrite-with-mapflatmap">Exercise 2 - rewrite with map/flatmap</h1>
<p>Readability matters. If we have this simple model:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">case</span> <span class="k">class</span> <span class="nc">User</span><span class="o">(</span><span class="n">name</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="n">email</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span>
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="k">class</span> <span class="nc">Prefs</span><span class="o">(</span><span class="n">theme</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">users</span> <span class="k">=</span> <span class="nc">Map</span><span class="o">(</span><span class="mi">1</span> <span class="o">-&gt;</span> <span class="nc">User</span><span class="o">(</span><span class="s">&#34;Alice&#34;</span><span class="o">,</span> <span class="nc">Some</span><span class="o">(</span><span class="s">&#34;a@b.com&#34;</span><span class="o">)),</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="nc">User</span><span class="o">(</span><span class="s">&#34;Bob&#34;</span><span class="o">,</span> <span class="nc">None</span><span class="o">))</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">prefs</span> <span class="k">=</span> <span class="nc">Map</span><span class="o">(</span><span class="s">&#34;a@b.com&#34;</span> <span class="o">-&gt;</span> <span class="nc">Prefs</span><span class="o">(</span><span class="nc">Some</span><span class="o">(</span><span class="s">&#34;dark&#34;</span><span class="o">)))</span></span></span></code></pre></div></div>
<p>then we can use (preferred! 😊) scala <code>for</code>:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala3">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">def getTheme(userId: Int): Option[String] =
</span></span><span class="line"><span class="cl">  for
</span></span><span class="line"><span class="cl">    user  &lt;- users.get(userId)
</span></span><span class="line"><span class="cl">    email &lt;- user.email
</span></span><span class="line"><span class="cl">    pref  &lt;- prefs.get(email)
</span></span><span class="line"><span class="cl">    theme &lt;- pref.theme
</span></span><span class="line"><span class="cl">  yield theme</span></span></code></pre></div></div>
<p>without which we would have to do this (don&rsquo;t! 😤):</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala3">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"> def getTheme2(userId: Int): Option[String] = {
</span></span><span class="line"><span class="cl">  users
</span></span><span class="line"><span class="cl">	.get(userId)
</span></span><span class="line"><span class="cl">    .flatMap(u =&gt; u.email)
</span></span><span class="line"><span class="cl">	.flatMap(e =&gt; prefs.get(e))
</span></span><span class="line"><span class="cl">	.flatMap(p =&gt;p.theme)
</span></span><span class="line"><span class="cl">}</span></span></code></pre></div></div>
<h1 id="note">Note</h1>
<p>Image was generated with this scala script:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"></code></pre></div></div>
<p>That&rsquo;s all for today.</p>
<p>Happy coding!</p>
]]></description>
</item>
<item>
    <title>Scala AND Rust ?</title>
    <link>/posts/2026-03-14_scala_and_rust/</link>
    <pubDate>Sat, 14 Mar 2026 05:44:57 &#43;0100</pubDate>
    <author>Kamila Chyla</author>
    <guid>/posts/2026-03-14_scala_and_rust/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/curriculum.jpg" referrerpolicy="no-referrer">
            </div><h1 id="science-based-programming-language-learning">Science based programming language learning</h1>
<p>Exploring two prorgamming languages at the same time seems like a bad idea, doesn&rsquo;t it? Well, good learning sources say that the best approaches to effective, expert learnings are:</p>
<ul>
<li>interleaving (study both languages concurrently — never sequentially)</li>
<li>spaced repetition</li>
<li>deliberate practice at the edge of your comfort zone</li>
<li>retrieval practice (close the docs)</li>
<li>and the explanation effect</li>
</ul>
<p>Looks like a very good idea to me.</p>
<ul>
<li>What if I could somehow optimize the learning process by utilizing  <em>all</em> of them?</li>
<li>What if I create a protocol with stuff I want to learn split into some stages and implement those science-based approaches to both &ldquo;ingest&rdquo; and &ldquo;practice&rdquo;?</li>
</ul>
<p>Risks:</p>
<ul>
<li>mental overwhelm - burnout, self-blame and all the internal struggle</li>
<li>ADD effect of not sticking to the protocol</li>
</ul>
<p>So I engaged AI for preparing</p>
<ul>
<li>the plan for learning Scala and Rust in parallel</li>
<li>the Anki deck for learning</li>
<li>and the SPA with the deck as well</li>
</ul>
<h1 id="the-plan">The plan</h1>
<p>This is the suplementary plan to the one I generated specifically for Scala in <a href="/en/posts/2026-02-27-scala-learning-path" rel="">Scala Learning Path</a>, however:</p>
<ul>
<li>original plan covers Scala only and is defined for 8 weeks</li>
<li>this plan covers both languages, Scala AND Rust</li>
</ul>
<h2 id="resources">Resources</h2>
<ul>
<li>
<p>🤩 <em>Curriculum</em>:  (online page): <a href="/webprojects/scala-rust/curriculum.html" rel="">Online Curriculum</a> (&lt;- explore the tabs!)</p>
</li>
<li>
<p>📗 <em>Deck</em> for Anki learning (download link): <a href="/webprojects/scala-rust/scala_rust_senior_desc.apkg" rel="">Anki Deck</a>
</p>
</li>
<li>
<p>🗓️ <em>Org-agenda</em> (for Emacs users - download link): <a href="/webprojects/scala-rust/scala_rust_curriculum.org" rel="">Org-agenda file</a>
</p>
</li>
</ul>
<p>I think I&rsquo;m ready!</p>
<h1 id="the-execution">The execution</h1>
<p>As an exercise, after I wrote simple anniversary lister in Rust (see <a href="https://github.com/kamchy/diary" target="_blank" rel="noopener noreffer ">diary</a>) I created the same program in Scala (see <a href="https://github.com/kamchy/diary_scala" target="_blank" rel="noopener noreffer ">scala-diary</a>).</p>
<h2 id="what-i-have-learned">What I have learned</h2>
<ol>
<li>Once you are slighly more familiar with one language your tendency is to use it for all auxiliatory tools. For example, to generate a list of events as input for both Rust and Scala versions I reach out to Rust (see <a href="https://github.com/kamchy/diary_generator]" target="_blank" rel="noopener noreffer ">Diary Generator</a>)</li>
<li>Writing <strong>unit tests</strong> <em>inside</em> a source file and <em>not</em> in a different directory helps to practice DDD, eliminating the need to switch between production and test code</li>
<li>Modelling <strong>errors</strong>: I used enums - in Rust I&rsquo;m aware of crates like thiserror and anyhow (two top-level on <a href="https://crates.io/keywords/error-handling" target="_blank" rel="noopener noreffer ">rates.io in error-handling category</a>)</li>
<li><strong>Enums</strong>: in Scala I used <a href="https://docs.scala-lang.org/scala3/reference/enums/enums.html" target="_blank" rel="noopener noreffer ">Scala Enums</a> as Left of the Either; in Rust I also modelled them using <a href="https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html" target="_blank" rel="noopener noreffer ">Rust Enums</a> in Result type.</li>
</ol>
<ul>
<li>those are different. Scala enums:
<ul>
<li>are &ldquo;used to define a type consisting of a set of named values&rdquo; (in scala 2 they were represented as objects)</li>
<li>are based on reflection</li>
<li>can be used as Java Enums by extending <code>java.lang.Enum</code>:</li>
</ul>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="n">enum</span> <span class="nc">ScalaEnum</span> <span class="n">extebds</span> <span class="nc">Enum</span><span class="o">[</span><span class="kt">ScalaEnum</span><span class="o">]</span><span class="k">:</span>
</span></span><span class="line"><span class="cl">  <span class="kt">case</span> <span class="kt">ValueOne</span><span class="o">,</span> <span class="nc">ValueTwo</span></span></span></code></pre></div></div>
<ul>
<li>can have fields - and different shapes:</li>
</ul>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl">  <span class="n">enum</span> <span class="nc">EBase</span><span class="o">(</span><span class="k">val</span> <span class="n">n</span><span class="k">:</span><span class="kt">Int</span><span class="o">)</span><span class="k">:</span>
</span></span><span class="line"><span class="cl">    <span class="kt">case</span> <span class="kt">EOne</span><span class="o">(</span><span class="kt">val</span> <span class="kt">s:</span> <span class="kt">String</span><span class="o">)</span> <span class="kt">extends</span> <span class="kt">EBase</span><span class="o">(</span><span class="err">1</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="kt">case</span> <span class="kt">ETwo</span><span class="o">(</span><span class="kt">val</span> <span class="kt">d:</span> <span class="kt">java.time.Duration</span><span class="o">)</span> <span class="kt">extends</span> <span class="kt">EBase</span><span class="o">(</span><span class="err">2</span><span class="o">)</span></span></span></code></pre></div></div>
but then you cannot use <code>EnumClass.fromOrdinal</code> (obviously) which works only for non-parameterized enums (which still can have some constant data):
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="n">enum</span> <span class="nc">Foo</span><span class="o">(</span><span class="k">val</span> <span class="n">n</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span><span class="k">:</span>
</span></span><span class="line"><span class="cl">   <span class="kt">case</span> <span class="kt">Bar</span> <span class="kt">extends</span> <span class="kt">Foo</span><span class="o">(</span><span class="err">7</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">   <span class="kt">case</span>  <span class="kt">Baz</span> <span class="kt">extends</span> <span class="kt">Foo</span><span class="o">(</span><span class="err">345</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">scala&gt;</span> <span class="kt">Foo.Bar.n</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">res12</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">7</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">scala</span><span class="o">&gt;</span> <span class="nc">Foo</span><span class="o">.</span><span class="n">fromOrdinal</span><span class="o">(</span><span class="mi">0</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">res15</span><span class="k">:</span> <span class="kt">Foo</span> <span class="o">=</span> <span class="nc">Bar</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">scala</span><span class="o">&gt;</span> <span class="nc">Foo</span><span class="o">.</span><span class="n">fromOrdinal</span><span class="o">(</span><span class="mi">0</span><span class="o">).</span><span class="n">n</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">res16</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">7</span></span></span></code></pre></div></div>
<ul>
<li>previously (in scala 2.x) the pattern matching with exhaustiveness checking <em>and</em> with possibility to use different data required reaching out for sealed class hierarchies:</li>
</ul>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scala">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl">   <span class="k">sealed</span> <span class="k">class</span> <span class="nc">Base</span><span class="o">(</span><span class="k">val</span> <span class="n">n</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">   <span class="k">case</span> <span class="k">class</span> <span class="nc">One</span><span class="o">(</span><span class="n">s</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="n">t</span><span class="k">:</span> <span class="kt">java.time.LocalDate</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Base</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">   <span class="k">case</span> <span class="k">class</span> <span class="nc">Two</span><span class="o">(</span><span class="n">d</span><span class="k">:</span> <span class="kt">java.time.Duration</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Base</span><span class="o">(</span><span class="mi">2</span><span class="o">)</span></span></span></code></pre></div></div>
To be honest, the only valuable thing enums bring to the table - afaik - is its Enum&rsquo;s api (<code>.values</code>, <code>fromOrdinal(Int)</code>) - as stated <a href="https://docs.scala-lang.org/scala3/reference/enums/desugarEnums.html" target="_blank" rel="noopener noreffer ">in this explanation</a> - enums is just a syntactic sugar 🍭 for sealed classes.</li>
<li>Rust Enums are quite similar I think:
<ul>
<li>variants can have different shapes</li>
</ul>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-rust">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"></code></pre></div></div>
<ul>
<li>behave more like a sealed class hierarchy in Scala</li>
<li>can be pattern-matched as well</li>
</ul>
</li>
</ul>
<ol start="5">
<li>It is so cool to have scala REPL especially at the beginning of the journey. Rust does not have that.</li>
</ol>
<h1 id="resources-1">Resources</h1>
<h2 id="for-reading">For reading</h2>
<ul>
<li>Rust: it is cool to have
<ul>
<li>free <a href="https://doc.rust-lang.org/book/title-page.html" target="_blank" rel="noopener noreffer ">Rust Book</a></li>
<li>there is also <a href="https://doc.rust-lang.org/cargo/" target="_blank" rel="noopener noreffer ">Cargo Book</a></li>
</ul>
</li>
<li>Scala:
<ul>
<li><a href="https://docs.scala-lang.org/" target="_blank" rel="noopener noreffer ">official docs</a></li>
<li><a href="https://rockthejvm.com/tags/scala" target="_blank" rel="noopener noreffer ">articles on RockTheJVM blog</a></li>
<li><a href="https://www.scala-sbt.org/2.x/docs/en/" target="_blank" rel="noopener noreffer ">wip sbt book 2.x</a></li>
<li><a href="https://www.scala-sbt.org/1.x/docs/" target="_blank" rel="noopener noreffer ">sbt book 1.x</a></li>
</ul>
</li>
</ul>
<h2 id="for-experimenting">For experimenting</h2>
<ul>
<li>Rust: <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2024" target="_blank" rel="noopener noreffer ">https://play.rust-lang.org/?version=stable&mode=debug&edition=2024</a></li>
<li>Scala: <a href="https://scastie.scala-lang.org/" target="_blank" rel="noopener noreffer ">https://scastie.scala-lang.org/</a>  (or <code>scala-cli console</code> once you&rsquo;re done with installing <a href="https://get-coursier.io/docs/cli-overview" target="_blank" rel="noopener noreffer ">coursier</a> - which, to be honest, I don&rsquo;t fully grok yet)</li>
</ul>
<p>Happy Hacking!</p>
]]></description>
</item>
<item>
    <title>Scala learning path</title>
    <link>/posts/2026-02-27-scala-learning-path/</link>
    <pubDate>Fri, 27 Feb 2026 00:00:00 &#43;0000</pubDate>
    <author>Kamila Chyla</author>
    <guid>/posts/2026-02-27-scala-learning-path/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/weeks.png" referrerpolicy="no-referrer">
            </div><p>Perhaps Gemini could plan my learning of Scala?&hellip;</p>
<p>Yes, it can.</p>
<p>See:</p>
<ul>
<li><a href="./learning-scala.pdf" rel="">My learning path as .pdf</a>,</li>
<li><a href="./learning-scala.typ" rel="">My learning path as .typ sources</a>,</li>
</ul>
<p>I wish me good luck.</p>
<h1 id="credits">Credits</h1>
<p>Gemini.</p>
]]></description>
</item>
<item>
    <title>Back to Scala</title>
    <link>/posts/2026-02-26-scala/</link>
    <pubDate>Wed, 25 Feb 2026 00:00:00 &#43;0000</pubDate>
    <author>Kamila Chyla</author>
    <guid>/posts/2026-02-26-scala/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/cats-tapirs.png" referrerpolicy="no-referrer">
            </div><h1 id="discovery">Discovery</h1>
<p>Leaving a familiar ground of Java, Maven and Spring Boot, and switching back to another JVM language - Scala - shouldn&rsquo;t be a Big Deal, right?</p>
<p>Especially when once upon a time I did complete two Cursera courses about Scala and Functional Programming, which - as far as I remember - were really eye-opening, rewarding and funny.</p>
<p>Let&rsquo;s dive into remote memories&hellip;</p>
<p>When I was learning Clojure, I had one issue (no, it was not about parenthesis; those serve me well) and it was: learning Emacs. An adventure of its own. Also, some language concepts needed to settle in my head. My fingers needed to learn paredit shortcuts. And I had a lot of fun.</p>
<p>Kotlin was even more fun, and that&rsquo;s because it has brought a feeling of a deep relief: similar to Scala, but much simpler; with familiar non-lispy syntax; better Java and without such scary typesystem (not to mention I could use an excellent Jetbrains IDE).</p>
<p>I played with Golang and Rust. Both languages have a valuable property of being sufficienlty &ldquo;cathedral-ic&rdquo; to have:</p>
<ul>
<li>an excellent commandline tooling</li>
<li>comprehensive webpage</li>
<li>a comitee/team which decides the direction the language would follow</li>
<li>top-noth package / build management system (I ❤️Cargo!)</li>
<li>crazy smart devs doing briliant software (and a <em>lot</em> of it!)</li>
</ul>
<p>Now, I decided to refresh my memory and check how it is to learn and program with Scala.
So I left my Java land and set my navigation tools in the direction of Scala.</p>
<h1 id="confusion">Confusion</h1>
<p>First, I needed to install something, probably a scala compiler.</p>
<h2 id="which-one">Which one</h2>
<p>Wait, <em>there are two Scalas</em>:</p>
<ul>
<li>Scala 2 (which <a href="https://docs.scala-lang.org/overviews/core/binary-compatibility-of-scala-releases.html" target="_blank" rel="noopener noreffer ">seem not to be binary compatible</a> between releases)</li>
<li>and Scala 3 (which follows its own <a href="https://docs.scala-lang.org/scala3/reference/language-versions/binary-compatibility.html" target="_blank" rel="noopener noreffer ">compatibility rules</a></li>
</ul>
<p>Oh, do we have Python2 vs Python3 story here?
Oh, and each has its own LTS?</p>
<p>Good. It should not matter which Scala I use if I have a good tooling.</p>
<h2 id="what-should-i-install">What should I install</h2>
<p>I should follow <a href="https://docs.scala-lang.org/getting-started/install-scala.html#install-scala-on-your-computer" target="_blank" rel="noopener noreffer ">scala-lang instructions</a>, so I installed <a href="https://get-coursier.io/docs/cli-overview" target="_blank" rel="noopener noreffer ">coursier</a>.</p>
<ul>
<li>It installed <a href="https://scala-cli.virtuslab.org/" target="_blank" rel="noopener noreffer ">scala-cli</a> - not sure why I need it if for dependencies I have coursier and sbt, and for scripting I have ammonite? Ah, it has <a href="https://scala-cli.virtuslab.org/docs/guides/introduction/using-directives" target="_blank" rel="noopener noreffer ">using directives</a>, runs .sc files which might have top level statements</li>
<li>it installed <a href="https://www.scala-sbt.org/" target="_blank" rel="noopener noreffer ">sbt</a> which looks a bit complex to grasp (see <a href="https://www.scala-sbt.org/2.x/docs/en/index.html" target="_blank" rel="noopener noreffer ">sbt docs</a>) - my mental model is that it is maven replacement in Scala ecosystem</li>
<li>also, <a href="https://ammonite.io/" target="_blank" rel="noopener noreffer ">ammonite</a> - which should helo with scala scripting - worth checking out (udpate: it breaks on Ubuntu)</li>
<li>and <a href="https://scalameta.org/scalafmt/docs/installation.html" target="_blank" rel="noopener noreffer ">scalafmt</a> - nice, I hope scala code <em>can</em> be well formatted <em>automatically</em>!</li>
</ul>
<p>Do I need all of it? I&rsquo;m confused.</p>
<h2 id="metals">Metals</h2>
<p>There is a language server <a href="https://scalameta.org/metals/" target="_blank" rel="noopener noreffer ">metals</a> which just does not want to play well with VisualStudioCode. It just stops working. I&rsquo;m confused again.</p>
<p>Interestingly, it kinda works when I use <a href="https://helix-editor.com/" target="_blank" rel="noopener noreffer ">helix editor</a> - it is <a href="https://scalameta.org/metals/docs/editors/helix/" target="_blank" rel="noopener noreffer ">explicitly supported</a> but LSP features don&rsquo;t work as expected (compared to eg LSP support for Rust)</p>
<p>It supports Emacs, but <a href="https://scalameta.org/metals/docs/editors/emacs" target="_blank" rel="noopener noreffer ">after looking at the emacs config example</a> I&rsquo;m not sure I want to use it.</p>
<h2 id="intellij">Intellij</h2>
<p>In the end, I switched to Intelij as it seems to be more stable than Metals with VSCode. However, Scala plugin is it saying strange things to me sometimes and also shows red curly lines and then those lines disappear suddenly. So I&rsquo;m a bit confused.</p>
<h1 id="hands-to-code">Hands to code</h1>
<p>I found <a href="https://docs.scala-lang.org/toolkit/introduction.html" target="_blank" rel="noopener noreffer ">scala toolkit</a> and played a bit with it. Nice. On the <a href="https://docs.scala-lang.org/toolkit/introduction.html" target="_blank" rel="noopener noreffer ">toolkit introduction page</a> I found <em>six ways</em> of running the code. I looked at <a href="https://mill-build.org/mill/index.html" target="_blank" rel="noopener noreffer ">mill</a>, tried it and confused some commands with sbt.</p>
<p>If mill is simpler than sbt, then fine, but I don&rsquo;t do sbt-complex things (yet) so I&rsquo;ll stick with sbt.
Unless I get more confused with sbt than I am with mill.</p>
<h1 id="libraries">Libraries</h1>
<ul>
<li>cats</li>
<li>cats effects</li>
<li>tapir</li>
</ul>
<p>Would I live long enough to get it? I need a good Algebra book first I guess.</p>
<p>Today I learned on youtube that &ldquo;effects&rdquo; in &ldquo;cats effects&rdquo; have nothing to do with &ldquo;side effects&rdquo;. Confusion, again.</p>
<h1 id="the-journey-begins">The journey begins</h1>
<p>Even the most daunting and massive undertakings are accomplished through a series of small, manageable actions.</p>
<blockquote>
<p>&ldquo;A journey of a thousand miles begins with a single step.&rdquo;</p>
<p>Lao Tzu in &ldquo;Tao Te Ching&rdquo;</p>
</blockquote>
<p>Perhaps Gemini could plan my learning of Scala?&hellip;</p>
<h1 id="credits">Credits</h1>
<p>Happy cats and tapirs in server room generated with Gemini.</p>
]]></description>
</item>
</channel>
</rss>
