<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.1.1">Jekyll</generator><link href="https://www.toromtomtom.com/blog/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.toromtomtom.com/blog/" rel="alternate" type="text/html" /><updated>2022-03-21T06:47:44+01:00</updated><id>https://www.toromtomtom.com/blog/feed.xml</id><title type="html">Tom’s blog</title><subtitle>I blog about things I find out</subtitle><entry><title type="html">Giving presentations with LaTeX Beamer and pdfpc</title><link href="https://www.toromtomtom.com/blog/2021/10/17/pdfpc.html" rel="alternate" type="text/html" title="Giving presentations with LaTeX Beamer and pdfpc" /><published>2021-10-17T00:00:00+02:00</published><updated>2021-10-17T00:00:00+02:00</updated><id>https://www.toromtomtom.com/blog/2021/10/17/pdfpc</id><content type="html" xml:base="https://www.toromtomtom.com/blog/2021/10/17/pdfpc.html">&lt;p&gt;If you, like me, give scientific presentations from time to time, chances are that you are using LaTeX and its beamer class.
The output is usually a PDF file that can be shown with pretty much every PDF viewer in some full screen presentation mode.
A significantly more capable tool for displaying PDF presentations is &lt;a href=&quot;https://pdfpc.github.io/&quot;&gt;pdfpc&lt;/a&gt;.
It has a lot of nice features that are familiar from dedicated presentation tools like Microsoft PowerPoint or LibreOffice Impress, most importantly support for a dual-screen setup with a presenter view in addition to the full screen slides visible to the audience.&lt;/p&gt;

&lt;p&gt;One of the most useful features in my opinion is the ability to add presenter notes to every slide.
And the really cool thing is that you can embed these notes &lt;a href=&quot;https://github.com/pdfpc/pdfpc/pull/570&quot;&gt;invisibly&lt;/a&gt; into the PDF by using the LaTeX package pdfpc.
It may look like this:&lt;/p&gt;

&lt;div class=&quot;language-latex highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;\documentclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;beamer&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;\usepackage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;pdfpc&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;\newcommand&lt;/span&gt;&amp;lt;&amp;gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;\talknote&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;[1]&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;\only&lt;/span&gt;#2&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;\pdfpcnote&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;- #1&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;\relax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;\begin{document}&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;\begin{frame}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;Slide One&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;\talknote&lt;/span&gt;&amp;lt;1&amp;gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;This note is only shown in the beginning&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;\talknote&lt;/span&gt;&amp;lt;3-4&amp;gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;This note is shown for **some points**&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nt&quot;&gt;\begin{itemize}&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;\item&lt;/span&gt;&amp;lt;2-&amp;gt; A first point
		&lt;span class=&quot;k&quot;&gt;\item&lt;/span&gt;&amp;lt;3-&amp;gt; Another point
		&lt;span class=&quot;k&quot;&gt;\item&lt;/span&gt;&amp;lt;4-&amp;gt; Point number three
	&lt;span class=&quot;nt&quot;&gt;\end{itemize}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;\talknote&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;This note is shown all the time&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;\end{frame}&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;\begin{frame}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;Slide Two&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;\end{frame}&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;\end{document}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I defined a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;newcommand&lt;/code&gt; called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;talknote&lt;/code&gt; to be able to add overlay specifications to notes.
This way, I can easily add notes that are only displayed for some time while flicking through the overlays of a slide.
The notes are also formatted as list items (pdfpc understands Markdown).
The command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pdfpcnote&lt;/code&gt; is provided by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pdfpc&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;When opening the produced PDF file with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pdfpc&lt;/code&gt; and going through the slides, the presenter view looks like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/blog/assets/pdfpc1.png&quot; alt=&quot;First page&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/blog/assets/pdfpc2.png&quot; alt=&quot;Second page&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/blog/assets/pdfpc3.png&quot; alt=&quot;Third page&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/blog/assets/pdfpc4.png&quot; alt=&quot;Fourth page&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/blog/assets/pdfpc5.png&quot; alt=&quot;Fifth page&quot; /&gt;&lt;/p&gt;</content><author><name></name></author><summary type="html">If you, like me, give scientific presentations from time to time, chances are that you are using LaTeX and its beamer class. The output is usually a PDF file that can be shown with pretty much every PDF viewer in some full screen presentation mode. A significantly more capable tool for displaying PDF presentations is pdfpc. It has a lot of nice features that are familiar from dedicated presentation tools like Microsoft PowerPoint or LibreOffice Impress, most importantly support for a dual-screen setup with a presenter view in addition to the full screen slides visible to the audience.</summary></entry><entry><title type="html">Colored and word-based diff for svn</title><link href="https://www.toromtomtom.com/blog/2021/03/21/svn-word-diff.html" rel="alternate" type="text/html" title="Colored and word-based diff for svn" /><published>2021-03-21T00:00:00+01:00</published><updated>2021-03-21T00:00:00+01:00</updated><id>https://www.toromtomtom.com/blog/2021/03/21/svn-word-diff</id><content type="html" xml:base="https://www.toromtomtom.com/blog/2021/03/21/svn-word-diff.html">&lt;p&gt;At work, we use Subversion (yes, I know) for version control of the LaTeX sources of the papers we write.
One of the nice things about version control is the possibility of viewing diffs, which is really useful when collaborating on text.
However, LaTeX sources often have very long lines, which makes it hard to spot differences in the usual line-based &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;diff&lt;/code&gt;.
For viewing word-based differences, there is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wdiff&lt;/code&gt; instead.
To use colors for marking added and removed words, &lt;a href=&quot;https://homepages.inf.ed.ac.uk/imurray2/compnotes/cwdiff/&quot;&gt;Prof. Iain Murray has published a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cwdiff&lt;/code&gt; shell script&lt;/a&gt; in 2011.&lt;/p&gt;

&lt;p&gt;I have adapted that shell script a bit.
First, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tput setf&lt;/code&gt; didn’t work on my system, so I replaced it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tput setaf&lt;/code&gt;.
Next, the script now marks additions and removals only with colors.
Third, I played around with the color choices a bit until they looked good in my solarized color scheme.
Finally, the script compares the files given in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$6&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$7&lt;/code&gt;, which allows using it directly as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;svn&lt;/code&gt;s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;diff-cmd&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The complete shell script is below:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;diffnew&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;tput setaf 7&lt;span class=&quot;si&quot;&gt;)$(&lt;/span&gt;tput bold&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;diffold&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;tput setaf 1&lt;span class=&quot;si&quot;&gt;)$(&lt;/span&gt;tput bold&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;tput op&lt;span class=&quot;si&quot;&gt;)$(&lt;/span&gt;tput sgr0&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;

wdiff &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--start-delete&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;diffold&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--end-delete&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--start-insert&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;diffnew&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--end-insert&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$6&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$7&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-C2&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\['&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    | less
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I recommend that you read the well-documented &lt;a href=&quot;https://homepages.inf.ed.ac.uk/imurray2/compnotes/cwdiff/cwdiff&quot;&gt;original script&lt;/a&gt; for more background.&lt;/p&gt;</content><author><name></name></author><summary type="html">At work, we use Subversion (yes, I know) for version control of the LaTeX sources of the papers we write. One of the nice things about version control is the possibility of viewing diffs, which is really useful when collaborating on text. However, LaTeX sources often have very long lines, which makes it hard to spot differences in the usual line-based diff. For viewing word-based differences, there is wdiff instead. To use colors for marking added and removed words, Prof. Iain Murray has published a cwdiff shell script in 2011.</summary></entry><entry><title type="html">I finished my PhD</title><link href="https://www.toromtomtom.com/blog/2021/02/14/phd.html" rel="alternate" type="text/html" title="I finished my PhD" /><published>2021-02-14T00:00:00+01:00</published><updated>2021-02-14T00:00:00+01:00</updated><id>https://www.toromtomtom.com/blog/2021/02/14/phd</id><content type="html" xml:base="https://www.toromtomtom.com/blog/2021/02/14/phd.html">&lt;p&gt;It is now official!
After handing in my thesis in September and defending it in January, I can now call myself Dr.-Ing. (Doctor of Engineering).&lt;/p&gt;</content><author><name></name></author><summary type="html">It is now official! After handing in my thesis in September and defending it in January, I can now call myself Dr.-Ing. (Doctor of Engineering).</summary></entry><entry><title type="html">Using streams for purely functional random number generation in Scala</title><link href="https://www.toromtomtom.com/blog/2020/09/16/scala-random-stream.html" rel="alternate" type="text/html" title="Using streams for purely functional random number generation in Scala" /><published>2020-09-16T00:00:00+02:00</published><updated>2020-09-16T00:00:00+02:00</updated><id>https://www.toromtomtom.com/blog/2020/09/16/scala-random-stream</id><content type="html" xml:base="https://www.toromtomtom.com/blog/2020/09/16/scala-random-stream.html">&lt;p&gt;The generation of (pseudo-)random numbers is a perfect example for the differences between imperative (object-oriented) and purely functional programming.
Scala’s support for both of these programming paradigms means that we can translate between them.
In this post we start with the imperative random number generation from the Scala standard library and wrap it up in a purely functional random number generator.
This exemplifies how mutable objects can be used even in functional code if the mutability is not observable from the outside.
The key is a lazy data structure that queries a private mutable object on demand.&lt;/p&gt;

&lt;h1 id=&quot;imperative-random-number-generation&quot;&gt;Imperative random number generation&lt;/h1&gt;

&lt;p&gt;The scala standard library provides a random number generator in a class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Random&lt;/code&gt;, offering methods like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nextInt&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;rng&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;nextInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// -1170105035 &lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;nextInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 234785527&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;nextInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// -1360544799&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you see, subsequent calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nextInt&lt;/code&gt; on a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Random&lt;/code&gt; object produce different results.
Therefore, the expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rng.nextInt&lt;/code&gt; is neither &lt;em&gt;deterministic&lt;/em&gt; nor &lt;em&gt;referentially transparent&lt;/em&gt; - we could not replace all occurrences of that expression with a memoized value.
This is because calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nextInt&lt;/code&gt; has &lt;em&gt;side effects&lt;/em&gt; - it mutates the internal state of the object &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rng&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Whereas this is the idiomatic way to express random number generation in imperative programming, purely functional programming avoids side effects and mutation in favor of determinism and referential transparency.
You may now wonder whether it is possible to use an imperative random number generator like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.util.Random&lt;/code&gt; in a purely functional program at all.
The answer is yes.&lt;/p&gt;

&lt;h1 id=&quot;purely-functional-random-number-generation&quot;&gt;Purely functional random number generation&lt;/h1&gt;

&lt;p&gt;A purely functional random number generator can be expressed in Scala as follows:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RNG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;nextInt&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;RNG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;RNG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkRNG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// initialize with seed = 42&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;nextInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// (RNG(seed = 13), -1170105035) &lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;nextInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// (RNG(seed = 13), -1170105035) &lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;nextInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// (RNG(seed = 13), -1170105035) &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RNG&lt;/code&gt; objects are immutable and generating a random number returns a changed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RNG&lt;/code&gt; object instead of mutating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r&lt;/code&gt;.
The expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rng.nextInt&lt;/code&gt; is deterministic and referentially transparent.
Next we look into an implementation of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RNG&lt;/code&gt; trait that wraps an imperative random number generator.&lt;/p&gt;

&lt;h1 id=&quot;wrapping-an-imperative-random-number-generator-in-a-purely-functional-random-number-generator&quot;&gt;Wrapping an imperative random number generator in a purely functional random number generator&lt;/h1&gt;

&lt;p&gt;The fundamental idea of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RNG&lt;/code&gt; trait that it contains some immutable state that allows generating a deterministic random number stream.
One way to do this is to use the last generated number as the state and some mathemagical formula to produce the next state.
However, we can also make the stream of random numbers explicit:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkRNG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;RNG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StreamRNG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StreamRNG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;LazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RNG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;nextInt&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;RNG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;StreamRNG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;LazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;random&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkStream&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;LazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;nextInt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#::&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mkStream&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mkStream&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The important part is the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stream&lt;/code&gt; with its recursive inner function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mkStream&lt;/code&gt;.
It produces a lazily evaluated, deterministic stream of random numbers with a private, mutable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scala.util.Random&lt;/code&gt; object.
Elements of this stream are memoized, therefore the expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;random.nextInt&lt;/code&gt; is only evaluated once per stream element.&lt;/p&gt;

&lt;p&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StreamRNG&lt;/code&gt; object points to a specific element in the stream, and to get the next random number we just return the head of the stream and use the tail as the new state.
Different &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StreamRNG&lt;/code&gt; objects can point to different elements in the stream, but the overall sequence of elements is shared between them.
In addition, the head of the stream gets garbage-collected if it is no longer accessible by any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StreamRNG&lt;/code&gt; object.&lt;/p&gt;

&lt;h1 id=&quot;bonus-wrapping-a-purely-functional-random-number-generator-in-an-imperative-random-number-generator&quot;&gt;Bonus: Wrapping a purely functional random number generator in an imperative random number generator&lt;/h1&gt;

&lt;p&gt;The reverse direction is easier.&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyRandom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;RNG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkRNG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;nextInt&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rng2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;nextInt&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng2&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Saving the current state in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;var&lt;/code&gt; allows overriding it, restoring mutability.&lt;/p&gt;</content><author><name></name></author><summary type="html">The generation of (pseudo-)random numbers is a perfect example for the differences between imperative (object-oriented) and purely functional programming. Scala’s support for both of these programming paradigms means that we can translate between them. In this post we start with the imperative random number generation from the Scala standard library and wrap it up in a purely functional random number generator. This exemplifies how mutable objects can be used even in functional code if the mutability is not observable from the outside. The key is a lazy data structure that queries a private mutable object on demand.</summary></entry><entry><title type="html">Lazy sequences in the Scala standard library</title><link href="https://www.toromtomtom.com/blog/2020/05/16/laziness-in-scala.html" rel="alternate" type="text/html" title="Lazy sequences in the Scala standard library" /><published>2020-05-16T00:00:00+02:00</published><updated>2020-05-16T00:00:00+02:00</updated><id>https://www.toromtomtom.com/blog/2020/05/16/laziness-in-scala</id><content type="html" xml:base="https://www.toromtomtom.com/blog/2020/05/16/laziness-in-scala.html">&lt;p&gt;One way to learn the idioms and idiosyncrasies of a programming language is to follow the development of its standard library.
The Scala standard libary, for example, deprecated its data structure for lazy sequences &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt; and replaced it with a new data structure called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt; in the 2.13 release.
However, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt; has different laziness characteristics than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt;, which recently sparked &lt;a href=&quot;https://github.com/scala/bug/issues/11984&quot;&gt;some discussion on GitHub&lt;/a&gt;.
I found the discussion quite interesting and will try to illustrate the difference between both data structures in this post.&lt;/p&gt;

&lt;h1 id=&quot;stream&quot;&gt;Stream&lt;/h1&gt;

&lt;p&gt;This is a simplified version of the definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hd&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tl&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hd&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tl&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt; consists of cons cells with an eagerly evaluated head and a lazily evaluated tail.
When a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt; object is instantiated with expressions for the head and tail, only the head expression is immediately evaluated, whereas the tail is only evaluated when it is first accessed.
Therefore, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt; always looks like the following.
All cons cells have an evaluated head, and all cons cells except the last one have an evaluated tail pointing at the next cons cell.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[  head, tail--]--&amp;gt;[  head, tail--]--&amp;gt;[  head, UNEVALUATED  ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One way to construct such a stream is to use a recursive function.
By injecting some &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;println&lt;/code&gt;s we can see in what order the function calls and the expressions for the head and the tail are evaluated.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#::&lt;/code&gt; is syntactical sugar for creating a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt; cons cell:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Evaluating cell $i&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Evaluating head for cell $i&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#::&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Evaluating tail for cell $i&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can now force the evaluation of a few cons cells and observe the output.&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The output is:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Evaluating cell 0
Evaluating head for cell 0

Evaluating tail for cell 0
Evaluating cell 1
Evaluating head for cell 1

Evaluating tail for cell 1
Evaluating cell 2
Evaluating head for cell 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, the head of each cell is evaluated when the cell is constructed, but the tail is only evaluated to access the next cell.&lt;/p&gt;

&lt;h1 id=&quot;lazylist&quot;&gt;LazyList&lt;/h1&gt;

&lt;p&gt;This is a simplified version of the definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt;, the replacement for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hd&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tl&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;LazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now both head and tail are lazily evaluated.
Therefore, the actual cons cell is only &lt;em&gt;constructed&lt;/em&gt; when either head or tail are accessed.
Interestingly (and maybe confusingly), both head and tail are always evaluated together.
For example, accessing the head of an unevaluated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt; cons cell will construct the cons cell and also evaluate its tail.
Thus, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt; structures look like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[  head, tail--]--&amp;gt;[  head, tail--]--&amp;gt;UNEVALUATED
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With a recursive function to construct a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt; similar to the one shown above for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt; and equivalent accesses to the individual cons cells, we get the following output:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Evaluating cell 0

Evaluating head for cell 0
Evaluating tail for cell 0
Evaluating cell 1
Evaluating head for cell 1
Evaluating tail for cell 1
Evaluating cell 2

Evaluating head for cell 2
Evaluating tail for cell 2
Evaluating cell 3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The first call to construct the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt; evaluates neither the head nor the tail.
In that sense, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt; is lazier than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt;.
However, evaluating the third cons cell (containing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;) also invokes the function to construct the next cons cell.
Here, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt; is less lazy than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;One immediate conclusion refers to porting uses of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt;.
To exploit laziness in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt; in its current (Scala 2.13.2) version, it has to be used differently than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stream&lt;/code&gt;.
If you are using a recursive function to construct the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt;, make sure that you do the work in the expressions for head and tail, as these are lazily evaluated.
Everything you do in the function outside of these expressions will the evaluated as soon as the previous cons cell is evaluated, even if only the head of that previous cons cell is accessed.
So, for example, instead of&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkLazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;LazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;doExpensiveCalculation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#::&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkLazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;do&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkLazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;LazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;doExpensiveCalculation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#::&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkLazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;div class=&quot;language-scala highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkLazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;LazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;doExpensiveCalculation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#::&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkLazyList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At the time of this writing, a &lt;a href=&quot;https://github.com/scala/scala/pull/8985&quot;&gt;pull request&lt;/a&gt; for making the tail of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LazyList&lt;/code&gt; cons cell lazy again has been opened.&lt;/p&gt;</content><author><name></name></author><summary type="html">One way to learn the idioms and idiosyncrasies of a programming language is to follow the development of its standard library. The Scala standard libary, for example, deprecated its data structure for lazy sequences Stream and replaced it with a new data structure called LazyList in the 2.13 release. However, LazyList has different laziness characteristics than Stream, which recently sparked some discussion on GitHub. I found the discussion quite interesting and will try to illustrate the difference between both data structures in this post.</summary></entry><entry><title type="html">Producing pictures of formulas with the LaTeX standalone package</title><link href="https://www.toromtomtom.com/blog/2020/05/02/latex-formula-pictures.html" rel="alternate" type="text/html" title="Producing pictures of formulas with the LaTeX standalone package" /><published>2020-05-02T00:00:00+02:00</published><updated>2020-05-02T00:00:00+02:00</updated><id>https://www.toromtomtom.com/blog/2020/05/02/latex-formula-pictures</id><content type="html" xml:base="https://www.toromtomtom.com/blog/2020/05/02/latex-formula-pictures.html">&lt;p&gt;Just a quick post with some LaTeX snippet that I found very useful to produce nice pictures of formulas for online teaching.
It can be compiled with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pdflatex -shell-escape filename&lt;/code&gt; and you need to have poppler installed.
Then you get a nice, high-resolution png of a LaTeX formula.&lt;/p&gt;

&lt;div class=&quot;language-latex highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;\documentclass&lt;/span&gt;[
	convert=&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;command=&lt;span class=&quot;k&quot;&gt;\unexpanded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;pdftoppm&lt;span class=&quot;k&quot;&gt;\space&lt;/span&gt; -png &lt;span class=&quot;k&quot;&gt;\space&lt;/span&gt; -r &lt;span class=&quot;k&quot;&gt;\space&lt;/span&gt; 600 &lt;span class=&quot;k&quot;&gt;\space&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;\infile&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;\space&lt;/span&gt; &amp;gt; &lt;span class=&quot;k&quot;&gt;\outfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;,
	border=1
]&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;standalone&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;\begin{document}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;e &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt; m c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;$&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;\end{document}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Maybe that’s useful for someone.&lt;/p&gt;</content><author><name></name></author><summary type="html">Just a quick post with some LaTeX snippet that I found very useful to produce nice pictures of formulas for online teaching. It can be compiled with pdflatex -shell-escape filename and you need to have poppler installed. Then you get a nice, high-resolution png of a LaTeX formula.</summary></entry><entry><title type="html">Using the Sony WH-1000XM3 with PulseAudio as a Headphone only</title><link href="https://www.toromtomtom.com/blog/2020/04/25/bluetooth-headset.html" rel="alternate" type="text/html" title="Using the Sony WH-1000XM3 with PulseAudio as a Headphone only" /><published>2020-04-25T00:00:00+02:00</published><updated>2020-04-25T00:00:00+02:00</updated><id>https://www.toromtomtom.com/blog/2020/04/25/bluetooth-headset</id><content type="html" xml:base="https://www.toromtomtom.com/blog/2020/04/25/bluetooth-headset.html">&lt;p&gt;Due to the Corona-caused lock-down, I have been in many video calls via Skype, Zoom, etc.
At first, I used the integrated microphone of my laptop as well as some wired speakers plugged into the headphone jack.
But it turns out I also have to do some teaching via video conferencing software.
Therefore, I ordered a dedicated USB microphone (a FiFine K670) for better audio.
My plan was to use that microphone and my Sony WH-1000XM3 bluetooth headphones.&lt;/p&gt;

&lt;p&gt;Now the problem I encountered was that each time I had the headphones connected to the laptop and I started a Skype/Zoom/Whatever call, they &lt;em&gt;automatically&lt;/em&gt; went into HSP/HFP mode.
This is the bluetooth mode for calls, meaning that the microphone can be used, but the audio quality on the headphones is reduced.
I want the headphones to be in A2DP mode all the time, which has better audio quality, but turns off the integrated microphone in the headset.&lt;/p&gt;

&lt;p&gt;The reason for this automatic switch is a “feature” that was &lt;a href=&quot;https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/10.0/#automaticallyswitchbluetoothprofilewhenusingvoipapplications&quot;&gt;introduced in PulseAudio 10&lt;/a&gt;.
It automatically switches the bluetooth profile as soon as a “phone” application is started.
To turn off this behavior, I did the following (see the &lt;a href=&quot;https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/11.0/#optiontoautomaticallyswitchbluetoothprofiletohspmoreoften&quot;&gt;release notes of PulseAudio 11&lt;/a&gt; for background):&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;tom@klotz ~&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;man default.pa
&lt;span class=&quot;gp&quot;&gt;tom@klotz ~&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; .config/pulse
&lt;span class=&quot;gp&quot;&gt;tom@klotz ~&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cp&lt;/span&gt; /etc/pulse/default.pa .config/pulse
&lt;span class=&quot;gp&quot;&gt;tom@klotz ~&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;vi .config/pulse/default.pa
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;First, check the man pages for the path of the user-specific PulseAudio config file.
Then, create the corresponding path and copy the system-wide config file to the user-specific config file location.
Finally, find the following section in the config file:&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;.ifexists module-bluetooth-policy.so
load-module module-bluetooth-policy
.endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and add the option &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto_switch=0&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;.ifexists module-bluetooth-policy.so
load-module module-bluetooth-policy auto_switch=0
.endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This way, the bluetooth mode will never change automatically.&lt;/p&gt;

&lt;p&gt;Side note: it might also be a good idea to update Bluez to at least 5.52, as that version &lt;a href=&quot;https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/1845046&quot;&gt;fixes a bug&lt;/a&gt; with selecting the bluetooth mode.&lt;/p&gt;</content><author><name></name></author><summary type="html">Due to the Corona-caused lock-down, I have been in many video calls via Skype, Zoom, etc. At first, I used the integrated microphone of my laptop as well as some wired speakers plugged into the headphone jack. But it turns out I also have to do some teaching via video conferencing software. Therefore, I ordered a dedicated USB microphone (a FiFine K670) for better audio. My plan was to use that microphone and my Sony WH-1000XM3 bluetooth headphones.</summary></entry><entry><title type="html">The Hollywood Principle: functors are frameworks</title><link href="https://www.toromtomtom.com/blog/2019/10/01/hollywood.html" rel="alternate" type="text/html" title="The Hollywood Principle: functors are frameworks" /><published>2019-10-01T00:00:00+02:00</published><updated>2019-10-01T00:00:00+02:00</updated><id>https://www.toromtomtom.com/blog/2019/10/01/hollywood</id><content type="html" xml:base="https://www.toromtomtom.com/blog/2019/10/01/hollywood.html">&lt;p&gt;Recently I’ve been reading and thinking about type constructors in functional programming.
Often these type constructors correspond to a basic construct from category theory: functors (at least).
In programming, a functor is often described as something that “can be mapped over”, meaning that a type constructor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F[_]&lt;/code&gt; is a functor if you can define a function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map(a: F[A])(f: A =&amp;gt; B): F[B]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another way to think about a functor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F[_]&lt;/code&gt; is the following.
A value of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F[A]&lt;/code&gt; is different from a value of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; because you cannot apply a function of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A =&amp;gt; B&lt;/code&gt; to it.
Instead, you &lt;em&gt;lift&lt;/em&gt; the function to another function with the type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F[A] =&amp;gt; F[B]&lt;/code&gt;.
This lifting is essentially the same thing as mapping, but focuses on the function rather than on the value the function is applied to.
To emphasize this, we can swap the parameters of the function: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lift(f: A =&amp;gt; B)(a: F[A]): F[B]&lt;/code&gt;.
When only applying the first parameter of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lift&lt;/code&gt;, you obtain the lifted function of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F[A] =&amp;gt; F[B]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, the interesting aspect to think about is who controls the application of the function.
As long as you have a plain function of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A =&amp;gt; B&lt;/code&gt;, you can just apply it to a value of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; and get a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt;.
However, if you lift the function into a functor and apply it to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F[A]&lt;/code&gt;, you transfer the responsibility for calling the original function to the functor.
For example, if you lift a function into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Option[_]&lt;/code&gt; functor, it will be called once or not all; if you lift it into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List[_]&lt;/code&gt; functor, it might be called multiple times; and if you lift it into a functor like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Future[_]&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task[_]&lt;/code&gt;, it might be called at a much later time.&lt;/p&gt;

&lt;p&gt;This inversion of control is pretty much what the so-called “Hollywood Principle” is about: “don’t call us, we’ll call you”.
In object-oriented programming, the Hollywood Principle is associated with using a framework (where you give up control) rather than a library (where your retain control).
Thus, in some sense, functional type constructors are comparable to OO frameworks.
I find this an interesting way to approach functors and their relatives.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit: &lt;a href=&quot;https://lobste.rs/s/ok7ig8/hollywood_principle_functors_are&quot;&gt;Discussion on lobste.rs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content><author><name></name></author><summary type="html">Recently I’ve been reading and thinking about type constructors in functional programming. Often these type constructors correspond to a basic construct from category theory: functors (at least). In programming, a functor is often described as something that “can be mapped over”, meaning that a type constructor F[_] is a functor if you can define a function map(a: F[A])(f: A =&amp;gt; B): F[B].</summary></entry><entry><title type="html">Running Fail2Ban and PF on FreeBsd 12.0</title><link href="https://www.toromtomtom.com/blog/2019/07/14/pf-fail2ban.html" rel="alternate" type="text/html" title="Running Fail2Ban and PF on FreeBsd 12.0" /><published>2019-07-14T00:00:00+02:00</published><updated>2019-07-14T00:00:00+02:00</updated><id>https://www.toromtomtom.com/blog/2019/07/14/pf-fail2ban</id><content type="html" xml:base="https://www.toromtomtom.com/blog/2019/07/14/pf-fail2ban.html">&lt;p&gt;I just spent more time than I’m willing to admit by looking into the combination of &lt;a href=&quot;https://www.freebsd.org/doc/handbook/firewalls-pf.html&quot;&gt;pf&lt;/a&gt;, &lt;a href=&quot;https://www.fail2ban.org/&quot;&gt;fail2ban&lt;/a&gt;, and jails on FreeBSD 12.0.
In particular, I am running a mail server in a jail and use pf to redirect all SMTP traffic to it.
The setup for the redirection follows a &lt;a href=&quot;https://forums.freebsd.org/threads/howto-quick-setup-of-jail-on-zfs-using-ezjail-with-pf-nat.30063/&quot;&gt;post on the FreeBSD forum&lt;/a&gt; that I stumbled upon when I initially set up the server.
Shortly after that I installed fail2ban and, as described in the setup instructions, inserted the line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anchor f2b/*&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/pf.conf&lt;/code&gt;.
I configured fail2ban to block access to the SSH port for anyone who tried to log in three times without success.
That was easy to test and worked perfectly.
I also wanted fail2ban to block SMTP access to the mail server for anyone who tried funny things with it (which happens shockingly fast after getting a public DNS entry for the domain).
However, I never really tested the SMTP port blocking.
Only now, some 6 months later, I noticed that fail2ban never blocked the SMTP port (i.e., the redirection to the mail jail).
I could login to the server and (unsuccessfully, of course) try to send spam to other domains as often as I wanted.
After trying out all kinds of configurations, I found out that the reason was in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/pf.conf&lt;/code&gt;.
I had some config like the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# router-facing interface 
ext_if=&quot;re0&quot; 

# LAN IP address
ext_ip=192.168.xxx.yyy

# jail subnet
jails=&quot;{10.1.1.0/24}&quot;

# NAT for the jails
nat on $ext_if proto {tcp udp icmp} from $jails to any -&amp;gt; $ext_ip

# Redirection to the jails based on port
# The keyword pass in the lines below caused my problems.
# - http
rdr pass on $ext_if proto tcp from any to $ext_ip port http -&amp;gt; 10.1.1.xxx
# - smtp
rdr pass on $ext_if proto tcp from any to $ext_ip port smtp -&amp;gt; 10.1.1.yyy
# etc.

# block all traffic by default
block all

# anchor for fail2ban rules
anchor &quot;f2b/*&quot;

# pass traffic to jails
pass in on $ext_if proto tcp from any to any port {http, smtp} keep state

# pass outbound traffic
pass out quick on $ext_if keep state
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The problem was that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rdr&lt;/code&gt; directives contain the keyword &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pass&lt;/code&gt;.
I copied that from the &lt;a href=&quot;https://forums.freebsd.org/threads/howto-quick-setup-of-jail-on-zfs-using-ezjail-with-pf-nat.30063/&quot;&gt;FreeBSD forum post&lt;/a&gt; without really thinking very much about it (pure cargo cult).
But what this did was make all traffic to the jails pass &lt;em&gt;before&lt;/em&gt; the fail2ban rules in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f2b&lt;/code&gt; anchor hierarchy were even checked.
The SSH traffic was not redirected to any jail, so it was correctly blocked by the anchor.
The SMTP traffic, however, was not checked against the rules created by fail2ban.
Just removing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pass&lt;/code&gt; from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rdr&lt;/code&gt; directives fixed this.
I even had the directive to pass the traffic to the jails in place already.&lt;/p&gt;</content><author><name></name></author><summary type="html">I just spent more time than I’m willing to admit by looking into the combination of pf, fail2ban, and jails on FreeBSD 12.0. In particular, I am running a mail server in a jail and use pf to redirect all SMTP traffic to it. The setup for the redirection follows a post on the FreeBSD forum that I stumbled upon when I initially set up the server. Shortly after that I installed fail2ban and, as described in the setup instructions, inserted the line anchor f2b/* into /etc/pf.conf. I configured fail2ban to block access to the SSH port for anyone who tried to log in three times without success. That was easy to test and worked perfectly. I also wanted fail2ban to block SMTP access to the mail server for anyone who tried funny things with it (which happens shockingly fast after getting a public DNS entry for the domain). However, I never really tested the SMTP port blocking. Only now, some 6 months later, I noticed that fail2ban never blocked the SMTP port (i.e., the redirection to the mail jail). I could login to the server and (unsuccessfully, of course) try to send spam to other domains as often as I wanted. After trying out all kinds of configurations, I found out that the reason was in the /etc/pf.conf. I had some config like the following:</summary></entry><entry><title type="html">Configuring OpenLDAP server to allow Nextcloud users to change their password</title><link href="https://www.toromtomtom.com/blog/2019/02/17/openldap-nextcloud.html" rel="alternate" type="text/html" title="Configuring OpenLDAP server to allow Nextcloud users to change their password" /><published>2019-02-17T00:00:00+01:00</published><updated>2019-02-17T00:00:00+01:00</updated><id>https://www.toromtomtom.com/blog/2019/02/17/openldap-nextcloud</id><content type="html" xml:base="https://www.toromtomtom.com/blog/2019/02/17/openldap-nextcloud.html">&lt;p&gt;The Nextcloud documentation contains a section about &lt;a href=&quot;https://docs.nextcloud.com/server/15/admin_manual/configuration_user/user_auth_ldap.html&quot;&gt;user authentication with LDAP&lt;/a&gt;.
For simple setups, users can authenticate via anonymous binds.
In that case, you don’t need a dedicated LDAP account with permissions to access the user accounts.&lt;/p&gt;

&lt;p&gt;If you want to allow users to change their own password, however, Nextcloud needs to access the LDAP server with an account that has write permissions for the users passwords.
I could not find any information on how to achieve this with an OpenLDAP server, so here is a short guide.&lt;/p&gt;

&lt;h1 id=&quot;create-the-account&quot;&gt;Create the account&lt;/h1&gt;

&lt;p&gt;First, you need to create an LDAP object for managing users.
Create an object with a password, for example a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;person&lt;/code&gt;.
Use an LDAP client of your choice for that, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ldapadd&lt;/code&gt;, or something else.
In my LDAP server, the user accounts that Nextcloud uses live under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ou=users,dc=example,dc=com&lt;/code&gt;, so I named the manager account &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;peopleManager&lt;/code&gt;.
It’s probably a good idea to create this manager account in a tree separate from your regular users, but I didn’t.&lt;/p&gt;

&lt;h1 id=&quot;configure-permissions&quot;&gt;Configure permissions&lt;/h1&gt;

&lt;p&gt;Next, we give the manager account the permission to access all user’s passwords without disrupting the existing permissions.
I created the following configuration in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slapd.conf&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;access to dn.subtree=&quot;ou=people,dc=example,dc=com&quot; attrs=userPassword
        by self write
        by dn=&quot;cn=peopleManager,ou=people,dc=example,dc=com&quot; write
        by anonymous auth
        by * none
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This lets users write their own password (e.g., when using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ldappasswd&lt;/code&gt;), but also gives the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;peopleManager&lt;/code&gt; write access to the password field.
Anonymous authentication is possible as well.&lt;/p&gt;

&lt;p&gt;The config file is &lt;a href=&quot;https://www.openldap.org/doc/admin24/access-control.html&quot;&gt;order-dependent&lt;/a&gt;, so insert the above before other access control configurations.&lt;/p&gt;

&lt;h1 id=&quot;password-policies&quot;&gt;Password policies&lt;/h1&gt;

&lt;p&gt;Finally, you will want to make sure that the passwords are stored with strong encryption.
To achieve that, you OpenLDAP server has to be compiled with the Password Policy overlay (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PPOLICY=ON&lt;/code&gt; on FreeBSD).
Then, add the following to your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slapd.conf&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Password hashing
password-hash {CRYPT}
password-crypt-salt-format &quot;$6$%.16s&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and, in your backend configuration (usually at the botton of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slapd.conf&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# force password hashing for clients (looking at you, nextcloud)
overlay ppolicy
ppolicy_hash_cleartext
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That should give you some pointers and terms to google for.&lt;/p&gt;</content><author><name></name></author><summary type="html">The Nextcloud documentation contains a section about user authentication with LDAP. For simple setups, users can authenticate via anonymous binds. In that case, you don’t need a dedicated LDAP account with permissions to access the user accounts.</summary></entry></feed>