<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Flipped Bits</title>
    <link rel="self" type="application/atom+xml" href="https://barafael.github.io/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://barafael.github.io"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-02-21T00:00:00+00:00</updated>
    <id>https://barafael.github.io/atom.xml</id>
    <entry xml:lang="en">
        <title>Stop Worrying and Learn to Loop-Select</title>
        <published>2025-02-21T00:00:00+00:00</published>
        <updated>2025-02-21T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/stop-worrying-and-learn-to-loop-select/"/>
        <id>https://barafael.github.io/posts/stop-worrying-and-learn-to-loop-select/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/stop-worrying-and-learn-to-loop-select/">&lt;p&gt;I can&#39;t seem to break from employing the &lt;code&gt;loop-select!&lt;/code&gt; pattern.
But what should merely be an intra-task concurrency primitive combining pattern matching and futures has sparked heated discussions.
While I begrudgingly acknowledge there are some footguns, here I&#39;ll advocate that actor-style programming &lt;em&gt;likes&lt;/em&gt; the &lt;code&gt;loop-select!&lt;/code&gt; (and so should you).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; In my previous post, I have looked at actor-style programming from the &lt;em&gt;outside&lt;/em&gt;. I have described my view of the preferrable public API of an actor, the influence of channels on the system architecture, and how to structure actors and full applications for &quot;natural actor shutdown&quot;. These relate to this article, wherein I peek into the inner workings of what an actor can look like in tokio/rust.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;hang-on-what-s-select-again&quot;&gt;Hang on - what&#39;s &lt;code&gt;select!&lt;/code&gt;, again?&lt;a class=&quot;zola-anchor&quot; href=&quot;#hang-on-what-s-select-again&quot; aria-label=&quot;Anchor link for: hang-on-what-s-select-again&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/macro.select.html&quot;&gt;&lt;code&gt;tokio::select!&lt;/code&gt;&lt;/a&gt; macro facilitates running several processes concurrently &lt;strong&gt;within one task&lt;/strong&gt;.
These processes can have completely different objectives, but because they run concurrently,
they may share or even mutate the local variables among each other without any locks.&lt;/p&gt;
&lt;p&gt;While the &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/macro.select.html&quot;&gt;docs on the &lt;code&gt;tokio::select!&lt;/code&gt; macro&lt;/a&gt; have improved massively in the last few releases,
here is another attempt at a simplified description:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Start several processes, and&lt;/li&gt;
&lt;li&gt;oversee their progress.&lt;/li&gt;
&lt;li&gt;Whenever one finishes, determine if its output matches our expectations for it, then
&lt;ul&gt;
&lt;li&gt;3a: if it did not, ignore the process, and go back to 2;&lt;/li&gt;
&lt;li&gt;3b: else, stop.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These processes, as you might imagine, are futures (1). Not tasks! Futures.&lt;/p&gt;
&lt;p&gt;The select macro will &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/future/trait.Future.html&quot;&gt;(informedly) poll&lt;/a&gt; each future under its supervision (2).
When a future is signalled to be woken, the macro will poll it (2).
This is not special, it is simply how futures are run.&lt;/p&gt;
&lt;p&gt;Finally, when a future returns &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/std/task/enum.Poll.html#variant.Ready&quot;&gt;&lt;code&gt;Poll::Ready(T)&lt;/code&gt;&lt;/a&gt;,
the resulting value is matched on a user-supplied pattern (3).
If the pattern does not match (3a), the macro disregards that process but continues monitoring the remaining ones.
Else, all other processes (futures) are canceled (3b) and the macro evaluates to the value yielded by the future.&lt;/p&gt;
&lt;h1 id=&quot;example-1-explicit-shutdown-requires-loop-select&quot;&gt;Example 1: Explicit shutdown requires &lt;code&gt;loop-select!&lt;/code&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#example-1-explicit-shutdown-requires-loop-select&quot; aria-label=&quot;Anchor link for: example-1-explicit-shutdown-requires-loop-select&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Imagine an actor which periodically sends a message into the world.
This actor shall stop running only when you tell it to, via a cancellation token.
No need to resort to aborting a task using &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/task/struct.JoinHandle.html#method.abort&quot;&gt;&lt;code&gt;JoinHandle::abort&lt;/code&gt;&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;The core of the &lt;code&gt;Beacon&lt;/code&gt; actor could look like this:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; async&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; event_loop&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;S&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;mut&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; token&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; CancellationToken&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; sink&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; S&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; Self&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    S&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Sink&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Unpin&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    S&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Debug&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; interval&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; interval&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Duration&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;from_secs&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    loop&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; First: get the next message.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        let&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; select!&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            _cancellation&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; token&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;cancelled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;                break&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            _&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; interval&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;tick&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;                self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Second: handle it.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        if&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; let&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; sink&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;send&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;await&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            tracing&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;warn!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;?&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Sink closed&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            break&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;        self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    self&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because the cancellation token and the interval are monitored concurrently, triggering the cancellation token will simply break the loop.
If it gets cancelled while the &quot;business logic&quot; is running, no problem - it will simply yield immediately on the next loop iteration.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: This test pauses time. That&#39;s an incredibly neat feature of tests in tokio - they run in stop-time (faster than light, sometimes)!. It works by skipping over any operations which are explicitly &quot;sleeping&quot; (such as &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/time/struct.Interval.html#method.tick&quot;&gt;&lt;code&gt;Interval::tick&lt;/code&gt;&lt;/a&gt;) &lt;strong&gt;if they are the only remaining operations right now&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: The trait bounds allow us to abstract over the kind of I/O resource we are actually using. It could be a TCP socket, websocket, webtransport socket, (wrapped) channel sender, or any other &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/futures/latest/futures/sink/trait.Sink.html#implementors&quot;&gt;implementor of the &lt;code&gt;futures::Sink&lt;/code&gt; trait&lt;/a&gt;. One frequent pattern is to wrap an I/O resource implementing the &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/io/trait.AsyncWrite.html&quot;&gt;&lt;code&gt;AsyncWrite&lt;/code&gt;&lt;/a&gt; trait by some type which then implements the &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/futures/latest/futures/sink/trait.Sink.html&quot;&gt;&lt;code&gt;Sink&lt;/code&gt;&lt;/a&gt; trait. The &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio-util/latest/tokio_util/codec/index.html&quot;&gt;&lt;code&gt;codec&lt;/code&gt;&lt;/a&gt; module of &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio-util/&quot;&gt;&lt;code&gt;tokio-util&lt;/code&gt;&lt;/a&gt; simplifies this pattern.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/barafael.github.io/tree/master/projects/explicit-actor-shutdown&quot;&gt;Full example&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;example-2-loop-select-enables-implicit-shutdown&quot;&gt;Example 2: &lt;code&gt;loop-select!&lt;/code&gt; enables Implicit Shutdown&lt;a class=&quot;zola-anchor&quot; href=&quot;#example-2-loop-select-enables-implicit-shutdown&quot; aria-label=&quot;Anchor link for: example-2-loop-select-enables-implicit-shutdown&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I don&#39;t think explicit shutdown is an anti-pattern, however usually I prefer implicit shutdown.
Imagine an actor similar to the previous one, which collects messages from a channel and sinks them into a TCP socket.
Additionally, it shall sink a specific (unchanging) message into the socket once per second.&lt;/p&gt;
&lt;p&gt;The core of the &lt;code&gt;Forwarder&lt;/code&gt; actor could look like this:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; async&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; event_loop&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;S&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; rx&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; mpsc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Receiver&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; sink&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; S&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; Self&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;where&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    S&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Sink&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Unpin&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    S&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Debug&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; interval&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; interval&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Duration&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;from_secs&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    loop&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; First: get the next message.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        let&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; select!&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rx&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;recv&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;                let&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;                    break&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                message&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            _&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; interval&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;tick&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;                PING&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Second: handle it.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        if&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; let&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; sink&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;send&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;await&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            tracing&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;warn!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;?&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Sink closed&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            break&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    self&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have &lt;a rel=&quot;external&quot; href=&quot;https://barafael.github.io/More-Actors-with-Tokio/&quot;&gt;previously argued&lt;/a&gt; that &quot;natural actor shutdown&quot; is &quot;best actor shutdown&quot;.
Here, we exit whenever the channel is closed naturally or in the unhappy case where our socket (sink) was closed remotely,
in which case we also have no more work to do.
The other actors sending us messages may react to this, as they will observe the forwarders absence eventually (certainly when they try to send it something).&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/barafael.github.io/tree/master/projects/implicit-actor-shutdown&quot;&gt;Full example&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;footguns-hiding-in-the-dark&quot;&gt;Footguns hiding in the dark&lt;a class=&quot;zola-anchor&quot; href=&quot;#footguns-hiding-in-the-dark&quot; aria-label=&quot;Anchor link for: footguns-hiding-in-the-dark&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;You may have noticed I have papered over the details.&lt;/p&gt;
&lt;h2 id=&quot;issue-1-cancellation-safety&quot;&gt;Issue #1: Cancellation Safety&lt;a class=&quot;zola-anchor&quot; href=&quot;#issue-1-cancellation-safety&quot; aria-label=&quot;Anchor link for: issue-1-cancellation-safety&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I stated that the futures in the competing concurrent branches of &lt;code&gt;select!&lt;/code&gt; are simply dropped when another arm &quot;wins&quot;.
If a future already internally commits some transaction (memory, network, database, whatever) before becoming &lt;code&gt;Poll::Ready&lt;/code&gt;, and is then dropped,
the transaction will of course not be reverted.
Or worse, if part of the transaction has happened, and the future is then dropped, the system may remain in an inconsistent state.
Most futures in tokio are marked cancellation safe in the docs. In the ecosystem, that annotation is less pervasive.
I haven&#39;t personally had problems with Cancellation Safety Violations (or am unaware), but it is something to keep in mind.&lt;/p&gt;
&lt;h2 id=&quot;issue-2-a-hidden-panic&quot;&gt;Issue #2: A hidden panic&lt;a class=&quot;zola-anchor&quot; href=&quot;#issue-2-a-hidden-panic&quot; aria-label=&quot;Anchor link for: issue-2-a-hidden-panic&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the examples above, we used &lt;code&gt;select!&lt;/code&gt; to produce a value of type &lt;code&gt;T&lt;/code&gt;.
And in the sequence, I have outlined how an arm will get disabled when it resolves but the pattern does not match.
So what happens if all arms become disabled? A &lt;code&gt;panic!&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: That&#39;s because a &lt;code&gt;panic!&lt;/code&gt; is one way to create a value of type &lt;code&gt;T&lt;/code&gt;, by creating a value of type &lt;code&gt;!&lt;/code&gt; (the never type). The never type is the only subtype in Rust, and it&#39;s a subtype of every other type. There is even an &lt;code&gt;impl From&amp;lt;!&amp;gt; for T&lt;/code&gt; somewhere, among other fun shenanigans.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here&#39;s a simple example:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;tokio&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    #&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;should_panic&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;expected &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;all branches are disabled and there is no else branch&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    async&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; select_nothing&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        let&lt;/span&gt;&lt;span&gt; _nonono&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; tokio&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;select!&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; async&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; None&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To fix it in this case, you can just add a &lt;code&gt;break&lt;/code&gt; as a &lt;code&gt;select!&lt;/code&gt; arm:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; zero&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; tokio&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;select!&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; async&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; None&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    else&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I like to &lt;code&gt;match&lt;/code&gt; or &lt;code&gt;let-else&lt;/code&gt; on the &lt;code&gt;mpsc&lt;/code&gt;-arm of the &lt;code&gt;select&lt;/code&gt; (there usually is one) and break there.
In other cases, one may want to break from the &lt;code&gt;loop-select&lt;/code&gt; when &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/io/trait.AsyncReadExt.html#method.read&quot;&gt;&lt;code&gt;read&lt;/code&gt;&lt;/a&gt;ing an &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/io/trait.AsyncRead.html&quot;&gt;&lt;code&gt;AsyncRead&lt;/code&gt;&lt;/a&gt; returns &lt;code&gt;0&lt;/code&gt; (no more bytes to be had).&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/barafael.github.io/tree/master/projects/select-examples&quot;&gt;Full example&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;issue-3-easy-to-create-an-infinite-busy-loop&quot;&gt;Issue #3: Easy to create an infinite busy loop&lt;a class=&quot;zola-anchor&quot; href=&quot;#issue-3-easy-to-create-an-infinite-busy-loop&quot; aria-label=&quot;Anchor link for: issue-3-easy-to-create-an-infinite-busy-loop&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Imagine having an actor to collect messages from three mpsc channels (for sake of example, it&#39;s not terribly important).
One could (I did) write such an event loop:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; async&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; event_loop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    mut&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    mut&lt;/span&gt;&lt;span&gt; rx1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; mpsc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Receiver&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    mut&lt;/span&gt;&lt;span&gt; rx2&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; mpsc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Receiver&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    mut&lt;/span&gt;&lt;span&gt; rx3&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; mpsc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Receiver&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    loop&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        tracing&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;info!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;waiting for message&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; First: get the next message.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        let&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; select!&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rx1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;recv&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                message&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rx2&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;recv&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                message&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rx3&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;recv&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                message&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Second: handle it.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        tracing&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;info!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ?&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;got message&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;        self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once all channel handles have been dropped, every pattern always matches (even though it will always be &lt;code&gt;None&lt;/code&gt;).
Then, we get our useless tracing output, and finally, we start from top.
I decided to include this example because busy loops like this are especially bad in an &lt;code&gt;async&lt;/code&gt; world.
The only solace offered here is that the loop is &lt;code&gt;async-busy&lt;/code&gt;, that is, at least it does not permanently hog the CPU.
It is busy in the sense that it can always run, but at least &lt;code&gt;tokio&lt;/code&gt; won&#39;t let it suffocate the other tasks.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/barafael.github.io/tree/master/projects/infinite-busy-loop-via-select&quot;&gt;Full example&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;issue-4-tooling&quot;&gt;Issue #4: Tooling&lt;a class=&quot;zola-anchor&quot; href=&quot;#issue-4-tooling&quot; aria-label=&quot;Anchor link for: issue-4-tooling&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Rustfmt&lt;/code&gt; simply does not touch anything within a &lt;code&gt;select&lt;/code&gt;, and Rust Analyzer also struggles with it.
That&#39;s not surprising, as the syntax is obviously invalid Rust to it.&lt;/p&gt;
&lt;p&gt;I like to take it as an incentive to create functions for all event handlers.
Here&#39;s my recommended approach: in your &lt;code&gt;select&lt;/code&gt;, only bother with message/event collection and shutdown.
The &lt;code&gt;select&lt;/code&gt;, at the start of the event loop, shall only produce a value of a type &lt;code&gt;Event&lt;/code&gt; or similar.
Then, after collecting the event, a method &lt;code&gt;on_event&lt;/code&gt; can be called.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; async&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; event_loop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;mut&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; rx&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; mpsc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Receiver&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Message&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    loop&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Collect some event.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        let&lt;/span&gt;&lt;span&gt; event&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; select!&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rx&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;recv&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;                let&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;                    break&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;                Event&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Message&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; status&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;tasks&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;next&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;                Event&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;TaskStatus&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; status&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Process the event.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        if&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; let&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;on_event&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;event&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            warn!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;?&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Error processing event&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Await completion of remaining tasks.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    while&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; let&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; status&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;tasks&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;next&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;await&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        if&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; let&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Err&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;on_task_status&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; status&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            warn!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;?&lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Error processing task status&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    self&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/barafael.github.io/tree/master/projects/nice-loop-select&quot;&gt;Full example&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>More Actors with Tokio</title>
        <published>2025-02-19T00:00:00+00:00</published>
        <updated>2025-02-19T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/more-actors-with-tokio/"/>
        <id>https://barafael.github.io/posts/more-actors-with-tokio/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/more-actors-with-tokio/">&lt;p&gt;In spring 2021, when I was first submerging into &lt;a rel=&quot;external&quot; href=&quot;https://tokio.rs&quot;&gt;tokio&lt;/a&gt;, a colleague and friend mentioned I should ingest this article:
&lt;a rel=&quot;external&quot; href=&quot;https://ryhl.io/blog/actors-with-tokio/&quot;&gt;Actors with Tokio&lt;/a&gt; by Alice Ryhl.
And, did I ingest it.
To summarize, the article proposes an architectural style which relies on
message passing (channels) and
inherent parallelism (tasks)
as well as
concurrency (via &lt;code&gt;async/.await&lt;/code&gt;)
to neatly and safely structure applications dealing with I/O.
But really, &lt;a rel=&quot;external&quot; href=&quot;https://ryhl.io/blog/actors-with-tokio/&quot;&gt;go read the article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Alice&#39;s post shaped and will continue to shape the asynchronous designs I take part in.
Unsurprisingly, I&#39;m not the only one - everybody working with Rust in network applications and beyond seems to relate.&lt;/p&gt;
&lt;p&gt;I have happily and successfully applied this &quot;actor&quot; architecture style over the last years.
Over this time, I have discovered a few minor adjustments to the proposed style for improved testability and composability.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; It is recommended to have read the aforementioned article before reading this one. In fact, &lt;strong&gt;if you&#39;re gonna read one article, &lt;a rel=&quot;external&quot; href=&quot;https://ryhl.io/blog/actors-with-tokio/&quot;&gt;read Alice&#39;s article&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;i-believe-that-an-actor-should-be-its-data&quot;&gt;I believe that an actor should &lt;em&gt;be&lt;/em&gt; its data&lt;a class=&quot;zola-anchor&quot; href=&quot;#i-believe-that-an-actor-should-be-its-data&quot; aria-label=&quot;Anchor link for: i-believe-that-an-actor-should-be-its-data&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Alice&#39;s post starts off with a recipe, briefly introducing the style by example.
Although the principle remains, I suggest a few changes.
In the original recipe, the actor holds its state &lt;em&gt;and its receiver&lt;/em&gt;.
What if an actor consisted solely of its plain-old-data state?&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;derive&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Debug&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; PartialEq&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Eq&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; struct&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; UniqueIdService&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    next_id&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An actor should not own channel handles or sockets or other I/O resources.
It may require them as arguments for its event loop of course! But not hold them as members.
&lt;strong&gt;Ownership is responsibility&lt;/strong&gt;, and who is really responsible for the run-time resources of the actor? The actor&#39;s event loop (see below).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; Holding simple data as actor state also simplifies restarting an actor after it broke out of its event loop: all you have to do is create new runtime resources and start the event loop again.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;i-prefer-the-event-loop-as-consuming-method&quot;&gt;I prefer the Event Loop as &lt;em&gt;consuming method&lt;/em&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#i-prefer-the-event-loop-as-consuming-method&quot; aria-label=&quot;Anchor link for: i-prefer-the-event-loop-as-consuming-method&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Somewhat differently to the original recipe, I prefer this particular event loop signature:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; UniqueIdService&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    pub&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; async&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; event_loop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;mut&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; rx&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; mpsc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Receiver&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Message&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notably, the event loop is a method &lt;em&gt;consuming and returning&lt;/em&gt; &lt;code&gt;Self&lt;/code&gt;.
It can be spawned as a task, but &lt;em&gt;doesn&#39;t have to&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;By returning &lt;code&gt;Self&lt;/code&gt;, we can inspect the state after the event loop finished, and even re-enter it.
And, we can assert that the correct target actor state has been reached in a &lt;a href=&quot;https://barafael.github.io/posts/more-actors-with-tokio/#simple-unit-test&quot;&gt;unit test&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;i-like-to-leave-the-spawning-to-the-user&quot;&gt;I like to leave the spawning to the user&lt;a class=&quot;zola-anchor&quot; href=&quot;#i-like-to-leave-the-spawning-to-the-user&quot; aria-label=&quot;Anchor link for: i-like-to-leave-the-spawning-to-the-user&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The original recipe &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/task/fn.spawn.html&quot;&gt;&lt;code&gt;tokio::spawn&lt;/code&gt;&lt;/a&gt;s the actor event loop in a helper function.
But who are we to assume that particular use? One may want to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;await the end of the event loop (without spawning),&lt;/li&gt;
&lt;li&gt;spawn, then monitor the &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/task/struct.JoinHandle.html&quot;&gt;&lt;code&gt;tokio::task::JoinHandle&amp;lt;_&amp;gt;&lt;/code&gt;&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;create the actor event loop future and put it in something like a &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/futures/latest/futures/stream/struct.FuturesUnordered.html&quot;&gt;&lt;code&gt;FuturesUnordered&lt;/code&gt;&lt;/a&gt; along with its brethren, or&lt;/li&gt;
&lt;li&gt;spawn the event loop future on a non-tokio executor.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&#39;s not to say you should not spawn the event loop onto some kind of task.
Spawning is great, and it lets an actor run free (employing parallelism) in its own little world (no foreign references, in or out).&lt;/p&gt;
&lt;h2 id=&quot;i-don-t-believe-in-actor-handles&quot;&gt;I don&#39;t believe in actor handles&lt;a class=&quot;zola-anchor&quot; href=&quot;#i-don-t-believe-in-actor-handles&quot; aria-label=&quot;Anchor link for: i-don-t-believe-in-actor-handles&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The original recipe recommends to implement an actor handle type.
Perhaps surprisingly, I have stopped writing actor handle types!
In my opinion, actor handles paper too much over the operations on the channel handle to the actor.
I feel they obscure what is actually happening and prevent us from doing &lt;em&gt;cool shit&lt;/em&gt;. We can&#39;t&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;await the termination of the actor (unless we forward &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/sync/mpsc/struct.Sender.html#method.closed&quot;&gt;&lt;code&gt;mpsc::Sender::closed&lt;/code&gt;&lt;/a&gt; of the underlying sender handle)&lt;/li&gt;
&lt;li&gt;store the response futures (&lt;code&gt;oneshot::Receiver&lt;/code&gt;s) in a combinator (&lt;a href=&quot;https://barafael.github.io/posts/more-actors-with-tokio/#simple-unit-test&quot;&gt;see unit test&lt;/a&gt;),&lt;/li&gt;
&lt;li&gt;use the actor handle from a blocking context,&lt;/li&gt;
&lt;li&gt;... much more &lt;em&gt;cool shit&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In short, &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/sync/mpsc/struct.Sender.html&quot;&gt;all the methods implemented on the &lt;code&gt;mpsc::Sender&lt;/code&gt;&lt;/a&gt; are there for good reasons, but our handle is hiding them.&lt;/p&gt;
&lt;p&gt;If you want to reduce boilerplate anyway: use associated functions on the actor (&lt;code&gt;UniqueIdService&lt;/code&gt;) type.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;///&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Query for a unique id.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;///&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;///&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Returns `None` if the actor is not running.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; async&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; get_unique_id&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sender&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;mpsc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Sender&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Message&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Option&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;oneshot&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Receiver&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;u32&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;callback&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; callback_receiver&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; oneshot&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;channel&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Message&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;GetUniqueId&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; callback&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sender&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;send&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;?&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;callback_receiver&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alternatively, an extension trait on &lt;code&gt;mpsc::Sender&amp;lt;Message&amp;gt;&lt;/code&gt; achieves the same ergonomics while keeping the full sender API accessible.&lt;/p&gt;
&lt;p&gt;I recommend to not fold in the &lt;code&gt;oneshot::Receiver&lt;/code&gt; like in the original handle implementation!&lt;/p&gt;
&lt;p&gt;By holding the receiver, you can collect and await it at your convenience.
For an example, see the &lt;a href=&quot;https://barafael.github.io/posts/more-actors-with-tokio/#simple-unit-test&quot;&gt;unit test&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;unit-testing-the-uniqueidservice&quot;&gt;&lt;a href=&quot;#simple-unit-test&quot; name=&quot;simple-unit-test&quot;&gt;&lt;/a&gt; Unit Testing the &lt;code&gt;UniqueIdService&lt;/code&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#unit-testing-the-uniqueidservice&quot; aria-label=&quot;Anchor link for: unit-testing-the-uniqueidservice&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I have found that actors which aren&#39;t easy to test hint at bad architecture. The interfaces should be clear, and all the other parties an actor talks to &lt;em&gt;should not need to be mocked&lt;/em&gt;:
the communication medium is some channel,
so one only needs to create such a channel and enqueue the correct messages on it (&lt;em&gt;before&lt;/em&gt; running the event loop, see below).&lt;/p&gt;
&lt;p&gt;Care must be taken to not run into timing-dependent behaviour in a unit test (and &lt;strong&gt;please avoid at great cost situations where you put a &lt;code&gt;sleep&lt;/code&gt; call in your test! It reeks&lt;/strong&gt;.
There is no way to ensure real-time constraints within tokio naively, so &lt;strong&gt;don&#39;t pretend there is&lt;/strong&gt; by bounding the execution time of your function under test).&lt;/p&gt;
&lt;p&gt;The actor interface as-is enables us to write a test with a deterministic order of events,
because we don&#39;t need to spawn a task running your actor and then send messages to it.
Instead, we enqueue the messages, then &lt;em&gt;drop the sender&lt;/em&gt;.
Only then, we await the event loop. Here we encounter &quot;natural actor shutdown&quot;. We can assert on the resulting final state.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;tokio&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; should_increment_unique_id&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; actor&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; UniqueIdService&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;tx&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; rx&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; mpsc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;channel&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; resp1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; UniqueIdService&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;get_unique_id&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;tx&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; resp2&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; UniqueIdService&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;get_unique_id&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;tx&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; resp3&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; UniqueIdService&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;get_unique_id&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;tx&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Important for this test:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    drop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;tx&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; service&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; actor&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;event_loop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;rx&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;await&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; nums&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; tokio&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;try_join!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;resp1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; resp2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; resp3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    assert_eq!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;nums&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    assert_eq!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;service&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; UniqueIdService&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; next_id&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: The event loop returns &lt;code&gt;Self&lt;/code&gt;. This means, even if you do need to spawn it, &lt;code&gt;.await&lt;/code&gt;ing the &lt;code&gt;tokio::task::JoinHandle&amp;lt;UniqueIdService&amp;gt;&lt;/code&gt; yields your actor state.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: One should generally, but especially in tests, await the completion of tasks somehow, if only to assert they did not panic. If you can, avoid placing asserts in test-only tasks.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2021&amp;amp;gist=bb316eb8bf6ab51602bfaedb2a841e70&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;ruling-out-deadlocks-with-bounded-channels&quot;&gt;&lt;a href=&quot;#bounded-mpsc-footgun&quot; name=&quot;bounded-mpsc-footgun&quot;&gt;&lt;/a&gt;Ruling out Deadlocks with Bounded Channels&lt;a class=&quot;zola-anchor&quot; href=&quot;#ruling-out-deadlocks-with-bounded-channels&quot; aria-label=&quot;Anchor link for: ruling-out-deadlocks-with-bounded-channels&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Attempting to send a message on a tokio bounded mpsc channel is &lt;code&gt;async&lt;/code&gt;, because the channel might be filled to the bound.
In that case, sending will &quot;suspend&quot; until space becomes available.
This is great, because it introduces &lt;em&gt;backpressure&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In normal operation, the mpsc queue compensates flow rate differences between sending and receiving.
However, imagine a situation where actor A sends actor B messages, while actor B sends actor A messages:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://barafael.github.io/posts/more-actors-with-tokio/actor-cycle.drawio.svg&quot; alt=&quot;Cyclic Actors&quot; /&gt;&lt;/p&gt;
&lt;p&gt;With both channels being bounded, the queue from A to B could become filled-to-the-bound.
Then, A would be blocked until B processes the next message, meaning A would process no messages.
If B now sends messages to A, they would not be processed, filling the channel to the bound.
Yikes! Deadlock.&lt;/p&gt;
&lt;p&gt;This situation is bad in another way, &lt;em&gt;even if the deadlock never arises&lt;/em&gt;.
The actor cycle prevents natural actor shutdown of A and B, because there always exists a handle to each receiver.
A and B are engaged in a sort of toxic nepotistic double binding.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; Strive for your channel topology to be a &lt;strong&gt;Directed Acyclic Graph&lt;/strong&gt; (see below).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;message-enums-are-great&quot;&gt;Message &lt;code&gt;enum&lt;/code&gt;s are great&lt;a class=&quot;zola-anchor&quot; href=&quot;#message-enums-are-great&quot; aria-label=&quot;Anchor link for: message-enums-are-great&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I have not changed a thing about the message type in the original recipe, because it&#39;s timeless.
Remember to make your messages own your data - don&#39;t borrow.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: A message is a way to transfer ownership from one actor to another, thereby transferring the responsibility to handle the data. Borrowing indicates time-coupling of components, which would defeat the purpose of autonomously running actors, so don&#39;t do it. Don&#39;t worry, if you do it, you&#39;ll end in lifetime soup and back out, anyway.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;More Note&lt;/em&gt;&lt;/strong&gt;: Sounds like a V-Table? &lt;a href=&quot;https://barafael.github.io/posts/more-actors-with-tokio/#ooop&quot;&gt;Not a coincidence&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;on-call-and-response&quot;&gt;On Call-and-Response&lt;a class=&quot;zola-anchor&quot; href=&quot;#on-call-and-response&quot; aria-label=&quot;Anchor link for: on-call-and-response&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most actors in my experience do not require and should not employ the call-response pattern demonstrated in this example. It&#39;s a sort of sync-async crossover anyway, and blocks the &quot;calling&quot; actor (when implemented naively). Look at the original post under the &quot;No responses to messages&quot; heading.&lt;strong&gt;Most actors I have seen simply take &quot;Commands&quot;, i.e. messages carrying the plain-old-data to be processed.&lt;/strong&gt;
The most fun designs I have been with did not use the pattern at all, and data flowed only left-to-right. This is good for a number of reasons, notably it &lt;a href=&quot;https://barafael.github.io/posts/more-actors-with-tokio/#bounded-mpsc-footgun&quot;&gt;prevents the biggest footgun of bounded mpsc channels&lt;/a&gt; and &lt;a href=&quot;https://barafael.github.io/posts/more-actors-with-tokio/#automatic-application-shutdown&quot;&gt;facilitates automatic application shutdown&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;i-like-natural-actor-shutdown&quot;&gt;&lt;a href=&quot;#automatic-application-shutdown&quot; name=&quot;automatic-application-shutdown&quot;&gt;&lt;/a&gt;I like &quot;Natural Actor Shutdown&quot;&lt;a class=&quot;zola-anchor&quot; href=&quot;#i-like-natural-actor-shutdown&quot; aria-label=&quot;Anchor link for: i-like-natural-actor-shutdown&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The actor scheme presented here still employs one of the most important aspects of the original design, which is &quot;natural actor shutdown&quot;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; let&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rx&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;recv&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;await&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;handle_message&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We exit when &lt;code&gt;recv&lt;/code&gt;ing on the channel yields &lt;code&gt;None&lt;/code&gt;.
As per &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/sync/mpsc/struct.Receiver.html#method.recv&quot;&gt;the docs&lt;/a&gt;, this happens when
there are no more messages in the &lt;code&gt;mpsc::Receiver&lt;/code&gt; queue, &lt;strong&gt;and&lt;/strong&gt;
there are no more &lt;code&gt;mpsc::Sender&lt;/code&gt;s.
In this situation, all messages have been handled, and no more senders can ever be created.
After exiting the event loop, but before returning from the function, an actor may run asynchronous cleanup logic
(such as unsubscribing from a message broker or closing a websocket connection).
After cleaning up, the event loop shall &lt;a href=&quot;https://barafael.github.io/posts/more-actors-with-tokio/#automatic-application-shutdown&quot;&gt;drop all runtime resources&lt;/a&gt;.
Other actors may then realize this situation and perform their own natural shutdown.&lt;/p&gt;
&lt;p&gt;If your entire system topology is a DAG, you can achieve graceful shutdown by dropping the &quot;top-level handle&quot;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://barafael.github.io/posts/more-actors-with-tokio/actor-dag.drawio.svg&quot; alt=&quot;DAG actor topology&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; If the task was spawned and isn&#39;t being joined somewhere, all actor resources are dropped. This includes channel handles of other actors.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;More Note:&lt;/em&gt;&lt;/strong&gt; Sounds like garbage collection? &lt;a href=&quot;https://barafael.github.io/posts/more-actors-with-tokio/#ooop&quot;&gt;Not a coincidence&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;what-about-explicit-shutdown&quot;&gt;What about Explicit Shutdown?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-about-explicit-shutdown&quot; aria-label=&quot;Anchor link for: what-about-explicit-shutdown&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;An actor should generally detect the condition where it is no longer needed and shut down by breaking out of its event loop.
I prefer this over explicitly shutting down an actor.
Ideally, shutdown naturally happens gracefully when each actor finishes processing and drops its actor handles.
Some designs do require distributing a &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio-util/latest/tokio_util/sync/struct.CancellationToken.html&quot;&gt;&lt;code&gt;tokio_util::sync::CancellationToken&lt;/code&gt;&lt;/a&gt; among the components, though.&lt;/p&gt;
&lt;h2 id=&quot;there-is-no-rust-actor-framework-and-it-s-called-tokio&quot;&gt;There is no Rust Actor Framework, and it&#39;s called &lt;code&gt;tokio&lt;/code&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#there-is-no-rust-actor-framework-and-it-s-called-tokio&quot; aria-label=&quot;Anchor link for: there-is-no-rust-actor-framework-and-it-s-called-tokio&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As a personal opinion of mine, and perhaps a spicy take: don&#39;t use an actor framework.
The ones I have seen are bad abstractions over &lt;code&gt;tokio::spawn&lt;/code&gt; and overly restrictive.&lt;/p&gt;
&lt;h2 id=&quot;don-t-make-a-heartbeat-actor&quot;&gt;Don&#39;t make a &lt;code&gt;Heartbeat&lt;/code&gt; Actor&lt;a class=&quot;zola-anchor&quot; href=&quot;#don-t-make-a-heartbeat-actor&quot; aria-label=&quot;Anchor link for: don-t-make-a-heartbeat-actor&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If your actor has the sole purpose of periodically announcing itself to the world, something is wrong.
If all other actors in the system are stuck or bogged down slow, should that heartbeat actor still run free? No.&lt;/p&gt;
&lt;h2 id=&quot;the-only-thing-better-than-an-actor-no-actor&quot;&gt;The only thing better than an actor: no actor&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-only-thing-better-than-an-actor-no-actor&quot; aria-label=&quot;Anchor link for: the-only-thing-better-than-an-actor-no-actor&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you can avoid an actor, do so. Try to delete as many actors from your design as possible.
Too many times I have observed that after an initial design, by deleting stuff from it, one can arrive at a beautiful final design.
If a region of your design doesn&#39;t feel right or look nice, &lt;strong&gt;trust your gut&lt;/strong&gt;: try to find the root cause of the strangeness, then try to eliminate it.
You may, like me, uncover corners that are incidentally complex and can be fixed.
Refuse to start implementation until you understand the problem (mind the &quot;unreasonable effectiveness of &lt;strong&gt;understanding the problem&lt;/strong&gt;&quot;).&lt;/p&gt;
&lt;h1 id=&quot;original-oop-ooop&quot;&gt;&lt;a href=&quot;#ooop&quot; name=&quot;ooop&quot;&gt;&lt;/a&gt;&quot;Original OOP&quot; (OOOP)&lt;a class=&quot;zola-anchor&quot; href=&quot;#original-oop-ooop&quot; aria-label=&quot;Anchor link for: original-oop-ooop&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Famously, Alan Kay &quot;didn&#39;t have C++ in mind&quot; when coining the term &quot;OOP&quot; (Object Oriented Programming).
This means inheritance, overloading, and a &lt;code&gt;class&lt;/code&gt; keyword are completely besides the point!
But what &lt;em&gt;did&lt;/em&gt; he have in mind?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.&lt;/p&gt;
&lt;p&gt;&lt;cite&gt;Alan Kay&lt;/cite&gt; in &lt;a rel=&quot;external&quot; href=&quot;https://www.purl.org/stefan_ram/pub/doc_kay_oop_en&quot;&gt;Dr. Alan Kay on the Meaning of “Object-Oriented Programming”&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Messaging: Passing data items along channels.&lt;/li&gt;
&lt;li&gt;local retention of state-process: in the event loop future, it&#39;s impossible to access any state. The message handler cannot be called from the outside once the event loop is running (not even if it were public).&lt;/li&gt;
&lt;li&gt;local protection of state-process: a tokio task is a panic boundary. An actor may crash, and the crash is observable from the outside, but it is recoverable. A panic cannot poison another actors&#39; data because a message cannot contain (non-static) references.&lt;/li&gt;
&lt;li&gt;hiding of state-process: actor state and message handler are private (not &lt;code&gt;pub&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;extreme late-binding of all things: actors are bound at spawn-time to other actors via channel handles. As discussed, a sender handle with a certain message type is like a v-table. Whatever is behind it only must know the message type. This is more late-bound than even &lt;code&gt;Box&amp;lt;dyn ...&amp;gt;&lt;/code&gt;, probably as late-bound as you can get in Rust.&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Load-Bearing Oneliners in the Rust Standard Library</title>
        <published>2022-09-14T00:00:00+00:00</published>
        <updated>2022-09-14T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/load-bearing-oneliners-in-the-rust-standard-library/"/>
        <id>https://barafael.github.io/posts/load-bearing-oneliners-in-the-rust-standard-library/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/load-bearing-oneliners-in-the-rust-standard-library/">&lt;p&gt;The Rust language tries to be as minimal as possible.
Many crucial features and design decisions aren&#39;t compiler magic, instead they live in &lt;code&gt;core&lt;/code&gt; or other parts of the standard library.
Here are some:&lt;/p&gt;
&lt;h1 id=&quot;shared-references-are-copy-look-don-t-touch&quot;&gt;Shared References are &lt;code&gt;Copy&lt;/code&gt; (look don&#39;t touch)&lt;a class=&quot;zola-anchor&quot; href=&quot;#shared-references-are-copy-look-don-t-touch&quot; aria-label=&quot;Anchor link for: shared-references-are-copy-look-don-t-touch&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The &lt;code&gt;core::marker::Copy&lt;/code&gt; trait marks a type which can be safely copied by simply copying its bits.
Think &lt;code&gt;bool&lt;/code&gt;, &lt;code&gt;f64&lt;/code&gt;, &lt;code&gt;Duration&lt;/code&gt;, or &lt;code&gt;SocketAddr&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A shared reference can obviously be copied. Owning a shared reference to a &lt;code&gt;T&lt;/code&gt;, i.e., a &lt;code&gt;&amp;amp;T&lt;/code&gt;, allows us to copy it.&lt;/p&gt;
&lt;p&gt;Here&#39;s the implementation of &lt;code&gt;core::marker::Copy&lt;/code&gt; for shared references:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;///&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Shared references can be copied, but mutable references *cannot*!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;stable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;feature &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;rust1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; since &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;1.0.0&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;impl&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ?&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Sized&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Copy&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;T&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(lives at: https://doc.rust-lang.org/src/core/marker.rs.html#839)&lt;/p&gt;
&lt;p&gt;This means, any shared reference to objects which aren&#39;t necessarily even &lt;code&gt;Sized&lt;/code&gt; can be copied.
That&#39;s why we even can call a method taking &lt;code&gt;&amp;amp;self&lt;/code&gt; - copy the pointer to &lt;code&gt;self&lt;/code&gt;, pass it to the method.&lt;/p&gt;
&lt;h1 id=&quot;drop-dead-gorgeous&quot;&gt;Drop-Dead Gorgeous&lt;a class=&quot;zola-anchor&quot; href=&quot;#drop-dead-gorgeous&quot; aria-label=&quot;Anchor link for: drop-dead-gorgeous&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;///&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; --- Doc comment omitted ---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;inline&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;stable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;feature &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;rust1&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; since &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;1.0.0&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;cfg_attr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;not&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; rustc_diagnostic_item &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;mem_drop&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; drop&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_x&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The function &lt;code&gt;drop&lt;/code&gt; is passed a &lt;code&gt;T&lt;/code&gt; without any trait bounds.
What can it do with a &lt;code&gt;T&lt;/code&gt;?
It cannot &lt;code&gt;Clone&lt;/code&gt; it, cannot do &lt;code&gt;Add&lt;/code&gt; or &lt;code&gt;Neg&lt;/code&gt;, cannot even &lt;code&gt;Display&lt;/code&gt;/&lt;code&gt;Debug&lt;/code&gt;.
And it isn&#39;t returning a value of &lt;code&gt;T&lt;/code&gt;!
There isn&#39;t much besides &lt;code&gt;{}&lt;/code&gt; that would be a valid function body:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Doing &lt;code&gt;unsafe&lt;/code&gt; things to look at &lt;code&gt;T&lt;/code&gt; (perilous, &lt;code&gt;T&lt;/code&gt; might not be &lt;code&gt;Sized&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Looping forever&lt;/li&gt;
&lt;li&gt;Producing a value of type &lt;code&gt;Never&lt;/code&gt; or &lt;code&gt;core::marker::Infallible&lt;/code&gt; (&lt;code&gt;panic&lt;/code&gt; and friends, or &lt;code&gt;std::process::exit&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Taking a shared reference to &lt;code&gt;_x&lt;/code&gt;, converting it to a usize, and storing it in a global &lt;code&gt;AtomicUsize&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; R&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; AtomicUsize&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; AtomicUsize&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; drop&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_x&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; r&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;_x&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    R&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;store&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; as&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; as&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; usize&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Ordering&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;SeqCst&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Playground: https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2021&amp;amp;gist=5e603039ddafeac0fdd599d78a59a13e&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Platform-Agnostic Driver for EBYTE-E32 LoRa Modules</title>
        <published>2022-05-10T00:00:00+00:00</published>
        <updated>2022-05-10T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/a-platform-agnostic-driver-for-ebyte-e32-lora-modules/"/>
        <id>https://barafael.github.io/posts/a-platform-agnostic-driver-for-ebyte-e32-lora-modules/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/a-platform-agnostic-driver-for-ebyte-e32-lora-modules/">&lt;p&gt;Radio communication is not easy, right? Well, unless it&#39;s complexities are hidden from us. That&#39;s why the nice people of &lt;a rel=&quot;external&quot; href=&quot;https://www.cdebyte.com/&quot;&gt;Ebyte&lt;/a&gt; have built the &lt;a rel=&quot;external&quot; href=&quot;https://www.ebyte.com/en/product-view-news.html?id=108&quot;&gt;E32 Modules&lt;/a&gt;. These modules allow for easy serial-based LoRa communication. Under the hood, they use the SX1278 modules which give us lots of power. Wouldn&#39;t it be nice to have a Rust driver for those easy to use modules?&lt;/p&gt;
&lt;h1 id=&quot;rust-driver&quot;&gt;Rust Driver&lt;a class=&quot;zola-anchor&quot; href=&quot;#rust-driver&quot; aria-label=&quot;Anchor link for: rust-driver&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Pretty bog-standard implementation of a driver that uses &lt;code&gt;embedded-hal&lt;/code&gt;. Provided with a couple GPIOs and a serial port, this driver will expose the functions &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt; from &lt;code&gt;embedded-hal&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For checking if you wired everything up correctly, you can get the model data as a nice rusty struct. For configuration, there are some nice data structures for all the different parameters and options the chip provides (different baud rates for UART and radio transmission, error correction, transmission power, of course channel and address, and some more). You can just inspect the settings of the chip, or store new ones temporarily or persistently.&lt;/p&gt;
&lt;p&gt;The implementation is scrutinized with mocking, proptests, and mutation tests. Also, it includes my first load-bearing usage of declarative macros.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/ebyte-e32-rs&quot;&gt;Ebyte E32 Rust Driver on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;demo-project-bare-metal-stm32f411-black-pill&quot;&gt;Demo Project (bare metal, STM32F411 Black Pill)&lt;a class=&quot;zola-anchor&quot; href=&quot;#demo-project-bare-metal-stm32f411-black-pill&quot; aria-label=&quot;Anchor link for: demo-project-bare-metal-stm32f411-black-pill&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/ebyte-e32-demo&quot;&gt;To be found here&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;cli-and-graphical-user-interfaces-for-testing&quot;&gt;CLI and graphical user interfaces for testing&lt;a class=&quot;zola-anchor&quot; href=&quot;#cli-and-graphical-user-interfaces-for-testing&quot; aria-label=&quot;Anchor link for: cli-and-graphical-user-interfaces-for-testing&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/ebyte-e32-ui&quot;&gt;Project here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The parameter types inside the driver optionally implement the &lt;code&gt;clap::ValueEnum&lt;/code&gt; derive macro behind the feature gate &lt;code&gt;&quot;value_enum&quot;&lt;/code&gt; (which also requires &lt;code&gt;std&lt;/code&gt;). This means, the enums can be used as part of a CLI! And, using the super powers of &lt;a rel=&quot;external&quot; href=&quot;https://github.com/MichalGniadek/klask&quot;&gt;klask&lt;/a&gt;, this CLI can be turned into a GUI. See &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/ebyte-e32-ui&quot;&gt;this project&lt;/a&gt; for how that goes! (I should probably blog about it).&lt;/p&gt;
&lt;p&gt;Sneak peek:
&lt;img src=&quot;https://barafael.github.io/posts/a-platform-agnostic-driver-for-ebyte-e32-lora-modules/ebyte-e32-gui.png&quot; alt=&quot;Image of GUI&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;blocking-operation&quot;&gt;Blocking Operation&lt;a class=&quot;zola-anchor&quot; href=&quot;#blocking-operation&quot; aria-label=&quot;Anchor link for: blocking-operation&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All operations are blocking, of course... Should be changed when &lt;code&gt;embedded-hal&lt;/code&gt; becomes &lt;code&gt;async&lt;/code&gt; or somehow supports non-blocking operation better than with &lt;code&gt;nb&lt;/code&gt; (technically, you could do non-blocking implementation now - &lt;code&gt;nb::Result&lt;/code&gt; gives you a &lt;code&gt;WouldBlock&lt;/code&gt; which you could work with).&lt;/p&gt;
&lt;h2 id=&quot;module-graph&quot;&gt;Module Graph&lt;a class=&quot;zola-anchor&quot; href=&quot;#module-graph&quot; aria-label=&quot;Anchor link for: module-graph&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;img src=https://barafael.github.io/processed_images/ebyte-e32-rs-mods.9ee9001531612b7f.png&gt;
&lt;p&gt;&lt;img src=&quot;https://barafael.github.io/posts/a-platform-agnostic-driver-for-ebyte-e32-lora-modules/ebyte-e32-rs-mods.png&quot; alt=&quot;Image of Module Graph&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;reduced-dependency-graph&quot;&gt;Reduced Dependency Graph&lt;a class=&quot;zola-anchor&quot; href=&quot;#reduced-dependency-graph&quot; aria-label=&quot;Anchor link for: reduced-dependency-graph&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://barafael.github.io/posts/a-platform-agnostic-driver-for-ebyte-e32-lora-modules/ebyte-e32-rs-deps.png&quot; alt=&quot;Image of Dependency Graph&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;prior-work&quot;&gt;Prior Work&lt;a class=&quot;zola-anchor&quot; href=&quot;#prior-work&quot; aria-label=&quot;Anchor link for: prior-work&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.mischianti.org/2019/10/21/lora-e32-device-for-arduino-esp32-or-esp8266-library-part-2/&quot;&gt;Renzo Mischiantis Ebyte E32 Library&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/xreef/LoRa_E32_Series_Library&quot;&gt;Same library on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks for your inspiration!&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to Communicate Failure in Rust</title>
        <published>2022-05-05T00:00:00+00:00</published>
        <updated>2022-05-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/how-to-communicate-failure-in-rust/"/>
        <id>https://barafael.github.io/posts/how-to-communicate-failure-in-rust/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/how-to-communicate-failure-in-rust/">&lt;p&gt;Basics explained well in this blog post: &lt;a rel=&quot;external&quot; href=&quot;https://www.sheshbabu.com/posts/rust-error-handling/&quot;&gt;Rust Error Handling&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The linked blog post shows how to manually create boxed errors and error enums.&lt;/p&gt;
&lt;h1 id=&quot;boxed-errors&quot;&gt;Boxed Errors&lt;a class=&quot;zola-anchor&quot; href=&quot;#boxed-errors&quot; aria-label=&quot;Anchor link for: boxed-errors&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Use boxed errors if you have a very wide set of sources which could produce errors (wide as in, many crates or many modules). Why? Because boxing an error is simple, but makes it harder to handle for the layer above you.&lt;/p&gt;
&lt;h1 id=&quot;error-enums&quot;&gt;Error Enums&lt;a class=&quot;zola-anchor&quot; href=&quot;#error-enums&quot; aria-label=&quot;Anchor link for: error-enums&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A custom error enum is the way to go if you want the user of the code you are working on to be able to check what exactly failed. You do have to create an enum variant for all the different error conditions. These could carry data, like source errors, backtraces, or even the input that caused the error (see e.g. &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/tokio/latest/tokio/sync/mpsc/error/struct.SendError.html&quot;&gt;SendError&lt;/a&gt;).&lt;/p&gt;
&lt;h1 id=&quot;apps-vs-libs&quot;&gt;Apps vs. Libs?&lt;a class=&quot;zola-anchor&quot; href=&quot;#apps-vs-libs&quot; aria-label=&quot;Anchor link for: apps-vs-libs&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;In many cases, applications use boxed errors and libs use error enums. But there are also counterexamples. I personally like error enums quite a bit, but this is a question of ergonomics, API design, and maybe taste.&lt;/p&gt;
&lt;h1 id=&quot;gee-that-s-lots-of-typing-for-both-approaches-it-doesn-t-have-to-be&quot;&gt;Gee, that&#39;s lots of typing for both approaches. It doesn&#39;t have to be!&lt;a class=&quot;zola-anchor&quot; href=&quot;#gee-that-s-lots-of-typing-for-both-approaches-it-doesn-t-have-to-be&quot; aria-label=&quot;Anchor link for: gee-that-s-lots-of-typing-for-both-approaches-it-doesn-t-have-to-be&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/anyhow/latest/anyhow/&quot;&gt;anyhow&lt;/a&gt; is even nicer than the &quot;Boxed-Error&quot; pattern and not too expensive to use.&lt;/p&gt;
&lt;p&gt;For error enums, the &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/thiserror/latest/thiserror/&quot;&gt;thiserror&lt;/a&gt; crate does all the manual work for you, and you get a nice way to declare your error codes that is completely invisible from outside of your crate or module.&lt;/p&gt;
&lt;h1 id=&quot;example-application-with-gui&quot;&gt;Example Application (with GUI!)&lt;a class=&quot;zola-anchor&quot; href=&quot;#example-application-with-gui&quot; aria-label=&quot;Anchor link for: example-application-with-gui&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/error-safari&quot;&gt;error-safari&lt;/a&gt; for some examples of both approaches.&lt;/p&gt;
&lt;h1 id=&quot;more-realistic-examples-please&quot;&gt;More Realistic Examples Please!&lt;a class=&quot;zola-anchor&quot; href=&quot;#more-realistic-examples-please&quot; aria-label=&quot;Anchor link for: more-realistic-examples-please&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A realistic usage of anyhow: &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/achat&quot;&gt;achat&lt;/a&gt;, a simple demo of different ways to implement network applications with tokio.&lt;/p&gt;
&lt;p&gt;Some realistic usages of thiserror can be found here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/pils/blob/main/src/error.rs&quot;&gt;pils&lt;/a&gt;, a simple lisp implementation inspired by &lt;a rel=&quot;external&quot; href=&quot;https://www.buildyourownlisp.com&quot;&gt;Build Your Own LISP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;(Silly code) &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/famous-last-words&quot;&gt;famous-last-words&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;(Silly code) &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/deutsche-bahn-delay-reasons&quot;&gt;Deutsche Bahn Delay Reasons&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Platform-Agnostic Driver for the CD74HC4067</title>
        <published>2021-03-21T00:00:00+00:00</published>
        <updated>2021-03-21T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/a-platform-agnostic-driver-for-the-cd74hc4067/"/>
        <id>https://barafael.github.io/posts/a-platform-agnostic-driver-for-the-cd74hc4067/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/a-platform-agnostic-driver-for-the-cd74hc4067/">&lt;p&gt;To read 16 analog values, one might use 16 pins with ADCs.
But depending on the required update rates and the available pins, this might be impossible.&lt;/p&gt;
&lt;p&gt;Instead, a simple 74HC4067 could be used.
It connects 1 of 16 analog IO lines to 1 signal line, depending on the 4 select pins.
The only thing to look out for is to disable the chip with the disable signal before changing the select pins to avoid activating an unwanted line during switching.&lt;/p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/cd74hc4067-rs&quot;&gt;74HC4067 driver&lt;/a&gt; described in this post requires just a couple embedded-hal GPIO pins.
It ensures that the multiplexer is disabled during the changing of the channel and makes no assumptions about what happens with the I/O pin.&lt;/p&gt;
&lt;h2 id=&quot;why-make-such-a-simple-driver&quot;&gt;Why make such a simple driver?&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-make-such-a-simple-driver&quot; aria-label=&quot;Anchor link for: why-make-such-a-simple-driver&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It is a simple driver for very simple hardware, yes. But any repetition saved is code and bugs saved!&lt;/p&gt;
&lt;p&gt;Additionally, this code serves as a good demonstration of testing using embedded-hal-mock and measuring test coverage using tarpaulin. And it serves as an example of type-state programming, it&#39;s advantages, and also ergonomics pitfalls.&lt;/p&gt;
&lt;h2 id=&quot;example-usage&quot;&gt;Example usage&lt;a class=&quot;zola-anchor&quot; href=&quot;#example-usage&quot; aria-label=&quot;Anchor link for: example-usage&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This code will activate random inputs. Working code for this on &lt;code&gt;stm32f0&lt;/code&gt; target can be found &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/cd74hc4067-rs/tree/main/stm32f0-example&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; delay&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Delay&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;/*&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; snip &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;*/&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; gpioa&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; dp&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;GPIOA&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;split&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;/*&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; snip &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;*/&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;pin_0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; pin_1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; pin_2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; pin_3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; pin_enable&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; disable_interrupts&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt;cs&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gpioa&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;pa0&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;into_push_pull_output&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cs&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;downgrade&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gpioa&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;pa1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;into_push_pull_output&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cs&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;downgrade&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gpioa&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;pa4&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;into_push_pull_output&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cs&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;downgrade&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gpioa&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;pa8&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;into_push_pull_output&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cs&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;downgrade&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gpioa&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;pa7&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;into_push_pull_output&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cs&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;downgrade&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; on_for&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; |&lt;/span&gt;&lt;span&gt;duration&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  pin&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;                  mut&lt;/span&gt;&lt;span&gt; hc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Cd74hc4067&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    Pin&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Output&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;PushPull&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    Pin&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Output&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;PushPull&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    DisabledState&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;set_channel_active&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pin&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; as&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u8&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;debugless_unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; enabled&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; hc&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;enable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;debugless_unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    delay&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;delay_ms&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;duration&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    enabled&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;disable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;debugless_unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; disabled&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    cd74hc4067&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Cd74hc4067&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pin_0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; pin_1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; pin_2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; pin_3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; pin_enable&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;debugless_unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; rng&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; RNG&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;WyRand&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u8&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0xDEADBEEF&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; delay_time_ms&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u32&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 2000&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;loop&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; generated&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u8&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rng&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;generate_range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 15&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    disabled&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; on_for&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;delay_time_ms&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; generated&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; disabled&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;advantages-of-typestate-programming&quot;&gt;Advantages of Typestate Programming&lt;a class=&quot;zola-anchor&quot; href=&quot;#advantages-of-typestate-programming&quot; aria-label=&quot;Anchor link for: advantages-of-typestate-programming&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The chip starts out in disabled mode&lt;/li&gt;
&lt;li&gt;The select pins can only be changed while the chip is disabled&lt;/li&gt;
&lt;li&gt;Once the chip is enabled, it must be disabled before anything can be done to it&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;cumbersome-usage-due-to-typestate-programming&quot;&gt;Cumbersome usage due to Typestate Programming&lt;a class=&quot;zola-anchor&quot; href=&quot;#cumbersome-usage-due-to-typestate-programming&quot; aria-label=&quot;Anchor link for: cumbersome-usage-due-to-typestate-programming&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The driver implementation relies on typestate programming for implementing the state transitions.
There are only 2 states, and the driver toggles between them as required.
In the &lt;code&gt;EnabledState&lt;/code&gt;, the multiplexer is active, and the active output channel cannot be changed.
In the &lt;code&gt;DisabledState&lt;/code&gt;, the multiplexer is not active, and the output channel can be selected.&lt;/p&gt;
&lt;p&gt;This makes the usage a little bit cumbersome, but it ensures that the driver can only be used safely while remaining efficient.&lt;/p&gt;
&lt;h2 id=&quot;line-coverage-and-phantomdata&quot;&gt;Line Coverage and PhantomData&lt;a class=&quot;zola-anchor&quot; href=&quot;#line-coverage-and-phantomdata&quot; aria-label=&quot;Anchor link for: line-coverage-and-phantomdata&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While writing unit tests while keeping an eye on the line coverage, I noticed that some lines would not be covered - and for a really good reason!
PhantomData markers are used in the code to disambiguate disabled and enabled states.
These markers are compile-time-only constructs - hence, line coverage cannot ever include them.
Neat.&lt;/p&gt;
&lt;p&gt;See here: &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/cd74hc4067-rs/blob/main/cd74hc4067/coverage.pdf&quot;&gt;coverage.pdf&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Platform-Agnostic driver for the HC12 serial radio module</title>
        <published>2021-03-21T00:00:00+00:00</published>
        <updated>2021-03-21T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/a-platform-agnostic-driver-for-the-hc12-serial-radio-module/"/>
        <id>https://barafael.github.io/posts/a-platform-agnostic-driver-for-the-hc12-serial-radio-module/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/a-platform-agnostic-driver-for-the-hc12-serial-radio-module/">&lt;p&gt;If only a serial port could be used without having to deal with cables!
The HC12 serial radio module enables just this super power.
It connects to a normal serial port, sending and receiving data to/from another hc12 module.&lt;/p&gt;
&lt;p&gt;The baud rate, transmission power, channel, and some other properties can be configured over the same serial interface, using simple AT commands.
To disambiguate the normal mode from the configuration mode, a digital signal is used.&lt;/p&gt;
&lt;p&gt;In this blog post, I introduce a simple embedded-hal driver for the hc12 module.
It requires a serial interface, a delay implementation, and a digital pin.&lt;/p&gt;
&lt;p&gt;Type-state is used to disambiguate the modes of operation: normal mode, configuration mode, and sleeping mode.
In normal mode, the driver instance can simply be used like any other serial device (with the Read and Write methods of the embedded-hal Serial trait).&lt;/p&gt;
&lt;h2 id=&quot;usage-example&quot;&gt;Usage example&lt;a class=&quot;zola-anchor&quot; href=&quot;#usage-example&quot; aria-label=&quot;Anchor link for: usage-example&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Full code &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/hc12-at-rs/tree/main/hc12-example-raspi&quot;&gt;here&lt;/a&gt;.
This example makes a driver instance, queries a few parameters, then sends a basic string over the hc12 repeatedly.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; uart&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Uart&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;9600&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Parity&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;None&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; set_pin&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Gpio&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;18&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;into_output&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; hc12&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; hc12_at&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;hc12&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Hc12&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;uart&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; set_pin&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; linux_embedded_hal&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Delay&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; hc12&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; match&lt;/span&gt;&lt;span&gt; hc12&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;into_configuration_mode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;assert!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;hc12&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;is_ok&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; buffer&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;u8&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 64&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; hc12&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;get_version&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;mut&lt;/span&gt;&lt;span&gt; buffer&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;:?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;from_utf8&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; params&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; hc12&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;get_parameters&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;:#?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; params&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;:?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; params&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;get_air_baud_rate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;    &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;:?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    params&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;get_air_baud_rate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;get_wireless_sensitivity_dbm&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; hc12&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; match&lt;/span&gt;&lt;span&gt; hc12&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;into_normal_mode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;loop&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hc12&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;write_buffer&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;hello hc12&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    thread&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;sleep&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Duration&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;from_millis&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;500&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;configuration&quot;&gt;Configuration&lt;a class=&quot;zola-anchor&quot; href=&quot;#configuration&quot; aria-label=&quot;Anchor link for: configuration&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The baudrate, radio channel, radio mode, and transmission power can be configured using AT commands.
To get the current configuration, the API function get_params can be used.&lt;/p&gt;
&lt;p&gt;Only some combinations of settings are valid though - the API should protect from misconfiguration.&lt;/p&gt;
&lt;p&gt;To get the air baud rate and the wireless sensitivity as specified in the &lt;a rel=&quot;external&quot; href=&quot;https://www.elecrow.com/download/HC-12.pdf&quot;&gt;datasheet&lt;/a&gt;, API functions get_air_baud_rate and get_wireless_sensitivity_dbm can be used.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fourier Transform of Cosine Function</title>
        <published>2018-08-08T00:00:00+00:00</published>
        <updated>2018-08-08T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/fourier-transform-of-cosine-function/"/>
        <id>https://barafael.github.io/posts/fourier-transform-of-cosine-function/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/fourier-transform-of-cosine-function/">&lt;p&gt;The Fourier transform maps a signal to its frequency spectrum, denoting exactly at which amplitude a given frequency appears in the signal.
The underlying assumption is that any signal out there can be decomposed in to an infinite sum of trigonometric functions with varying amplitude, phase, and frequency.
But what happens if one of the most basic functions, the cosine itself, is transformed?&lt;/p&gt;
&lt;h2 id=&quot;prerequisites-and-notation&quot;&gt;Prerequisites and Notation&lt;a class=&quot;zola-anchor&quot; href=&quot;#prerequisites-and-notation&quot; aria-label=&quot;Anchor link for: prerequisites-and-notation&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I will use&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;\widehat{f}&lt;/script&gt;
&lt;p&gt;to refer to the Fourier Transform of&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;f&lt;/script&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;I will use the following definition of the Fourier transform:&lt;/p&gt;
&lt;p&gt;Let&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;f \in L_2(\mathbb{R})&lt;/script&gt;
&lt;p&gt;be a signal. Then:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\widehat{f}(\xi) = \int_{-\infty}^{\infty}f(t)e^{-i\xi t}dt
&lt;/script&gt;
&lt;h2 id=&quot;transforming-the-cosine-function&quot;&gt;Transforming the Cosine Function&lt;a class=&quot;zola-anchor&quot; href=&quot;#transforming-the-cosine-function&quot; aria-label=&quot;Anchor link for: transforming-the-cosine-function&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;plugging-the-cosine-into-the-definition-of-the-fourier-transform&quot;&gt;Plugging the Cosine into the definition of the Fourier Transform&lt;a class=&quot;zola-anchor&quot; href=&quot;#plugging-the-cosine-into-the-definition-of-the-fourier-transform&quot; aria-label=&quot;Anchor link for: plugging-the-cosine-into-the-definition-of-the-fourier-transform&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\widehat{(cos)}(\xi) = 
\int_{-\infty}^{\infty}cos(t)e^{-i\xi t}dt = \\
\int_{-\infty}^{\infty}\frac{e^{it}+e^{-it}}{2}e^{-i\xi t}dt = \\
\frac{1}{2}\int_{-\infty}^{\infty}e^{it}e^{-i\xi t}dt + \frac{1}{2}\int_{-\infty}^{\infty}e^{-it}e^{-i\xi t}dt = \\
\frac{1}{2}\int_{-\infty}^{\infty}e^{it(1-\xi)}dt + \frac{1}{2}\int_{-\infty}^{\infty}e^{-it(1-\xi)}dt = \\
\frac{1}{2}\int_{-\infty}^{\infty}e^{-it(\xi-1)}dt + \frac{1}{2}\int_{-\infty}^{\infty}e^{-it(1-\xi)}dt = \\
\frac{1}{2}\int_{-\infty}^{\infty}1 e^{-it(\xi-1)}dt + \frac{1}{2}\int_{-\infty}^{\infty}1 e^{-it(1-\xi)}dt = \\
\frac{1}{2}\widehat{1}(\xi-1) + \frac{1}{2}\widehat{1}(1-\xi)
&lt;/script&gt;
&lt;p&gt;So we see that the spectrum of the cosine is comprised of two other certain spectra, which are shifted in time.&lt;/p&gt;
&lt;h3 id=&quot;but-what-is-the-fourier-transform-of-1&quot;&gt;But what is the fourier transform of 1?&lt;a class=&quot;zola-anchor&quot; href=&quot;#but-what-is-the-fourier-transform-of-1&quot; aria-label=&quot;Anchor link for: but-what-is-the-fourier-transform-of-1&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This can be approached using intuition. Given that the value of the spectrum of a function at frequency&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;\xi = 0&lt;/script&gt;
&lt;p&gt;is equal to the mean of the function:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\widehat{1}(0) = \int_{-\infty}^{\infty}1dt = \infty
&lt;/script&gt;
&lt;p&gt;We can conclude that our spectrum is infinite at 0. But what about the rest of the function?&lt;/p&gt;
&lt;p&gt;The 1-function does not have any other spectral components - it is boring and flat, completely defined without any frequency components other than 0.&lt;/p&gt;
&lt;p&gt;A function that is infinite at 0 and 0 everywhere else - sounds familiar? The Dirac Impulse function!&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\delta(t) =
\begin{cases}
0,  &amp; t \lt 0 \\
\infty,  &amp; t = 0 \\
0,  &amp; t \gt 0
\end{cases}
&lt;/script&gt;
&lt;p&gt;So, now that we have the transform of the 1-function (albeit the derivation was rather hand-wavy), we can state the fourier transform of the cosine function.&lt;/p&gt;
&lt;h3 id=&quot;final-result&quot;&gt;Final Result&lt;a class=&quot;zola-anchor&quot; href=&quot;#final-result&quot; aria-label=&quot;Anchor link for: final-result&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\frac{1}{2}\widehat{1}(\xi-1) + \frac{1}{2}\widehat{1}(1-\xi) = \\
\frac{1}{2}\delta(\xi-1) + \frac{1}{2}\delta(1-\xi)
&lt;/script&gt;
&lt;p&gt;The result: Two Impulses, one at 1, one at -1, suffice to describe the spectrum of the cosine function!&lt;/p&gt;
&lt;h2 id=&quot;what-about-cosine-functions-with-different-frequencies&quot;&gt;What about Cosine Functions with different Frequencies?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-about-cosine-functions-with-different-frequencies&quot; aria-label=&quot;Anchor link for: what-about-cosine-functions-with-different-frequencies&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A cosine can be given for any frequency by scaling it:&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;cos(a*t)&lt;/script&gt;
&lt;p&gt;where&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;a \in \mathbb{R}&lt;/script&gt;
&lt;p&gt;denotes the desired frequency.
We can write this using the scaling operator&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;\sigma_{a} f(\cdot) = f(a\cdot)&lt;/script&gt;
&lt;p&gt;. If we scale a function like that, we can try to imagine what will happen to the spectrum of the function: if we increase the frequency (&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;a \gt 1&lt;/script&gt;
&lt;p&gt;), we stretch the spectrum to accomodate the higher spectral components, and if we decrease the frequency (&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;a \lt 1&lt;/script&gt;
&lt;p&gt;), we compress the spectrum because there are now lower spectral components. Stated mathematically:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\sigma_{a}\widehat{f} = \frac{1}{a}\widehat{f}(\frac{\xi}{a})
&lt;/script&gt;
&lt;p&gt;Applying this to the Cosine yields:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\sigma_{a}\widehat{cos} = \frac{1}{a}\widehat{cos}(\frac{\xi}{a}) = \\
\frac{1}{a}\frac{1}{2}\delta(\frac{\xi-1}{a}) + \frac{1}{a}\frac{1}{2}\delta(\frac{1-\xi}{a})
&lt;/script&gt;
&lt;p&gt;As one might expect, transforming cosines of differing frequencies shifts the impulses around to the corresponding spectral frequencies.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Impulse Response and Transfer Function</title>
        <published>2018-07-08T00:00:00+00:00</published>
        <updated>2018-07-08T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/impulse-response-and-transfer-function/"/>
        <id>https://barafael.github.io/posts/impulse-response-and-transfer-function/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/impulse-response-and-transfer-function/">&lt;p&gt;Applying filters to signals is one of the most important applications of mathematics in signal processing.
But with all the Fourier transforms, Convolutions, and various properties like causality, time-invariance, linearity...  It can get confusing.
In this post, I want to clarify the relationship between a filter, it&#39;s impulse response and transfer function, and why applying a filter is the same as convoluting a transformed signal with an impulse response.
Don&#39;t worry, it will sound less intimidating in the end.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites-and-notation&quot;&gt;Prerequisites and Notation&lt;a class=&quot;zola-anchor&quot; href=&quot;#prerequisites-and-notation&quot; aria-label=&quot;Anchor link for: prerequisites-and-notation&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I will use&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;\widehat{c}&lt;/script&gt;
&lt;p&gt;to refer to the Fourier Transform of&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;c&lt;/script&gt;
&lt;p&gt;(and&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;(c + d)\hat{ }&lt;/script&gt;
&lt;p&gt;for the transform of larger terms).
Conversely, I will use the inverted hat for the inverse of the Fourier Transform:&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;c(t) = (\widehat{c}(\cdot))\vee(t)&lt;/script&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;To denote the Convolution of signals&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;c&lt;/script&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;d&lt;/script&gt;
&lt;p&gt;, I will use&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;c \ast d&lt;/script&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;The raw definitions are (incomplete for brevity):&lt;/p&gt;
&lt;p&gt;Let&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt; c \in l_2(\mathbb{Z}) &lt;/script&gt;
&lt;p&gt;be a signal. Then:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\widehat{c}(\xi) = \sum_{k \in \mathbb{Z}}c(k)e^{-i\xi k}
&lt;/script&gt;
&lt;p&gt;Let&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;c, d \in l_2(\mathbb{Z})&lt;/script&gt;
&lt;p&gt;. Then:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
(c \ast d)(\tau) = \sum_{k \in \mathbb{Z}}c(\tau - k)d(k)
&lt;/script&gt;
&lt;p&gt;A fundamental theorem in Signal Processing is the Convolution Theorem:&lt;/p&gt;
&lt;p&gt;Let&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;c, d \in l_2(\mathbb{Z})&lt;/script&gt;
&lt;p&gt;. Then:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\widehat{(c \ast d)}(\xi) = \widehat{c}(\xi)\widehat{d}(\xi)
&lt;/script&gt;
&lt;p&gt;The proof is included here for completeness, however it is &lt;strong&gt;not particularly important for the rest of the post, so feel free to skip it&lt;/strong&gt;:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\def\colonequals{:=}
\widehat{(c \ast d)}(\xi) = \\
\sum_{k \in \mathbb{Z}}(c \ast d)(k)e^{-i\xi k}= \\
\sum_{k \in \mathbb{Z}}\sum_{s\in\mathbb{Z}}c(k-s)d(s) e^{-i\xi k}=\\ \sum_{k \in \mathbb{Z}}\sum_{s\in\mathbb{Z}}c(k-s)d(s) e^{-i\xi (k-s+s)}=\\
\sum_{k \in \mathbb{Z}}\sum_{s\in\mathbb{Z}}c(k-s)d(s) e^{-i\xi (k-s)}e^{-i\xi s}=\\
\sum_{k \in \mathbb{Z}}\sum_{s\in\mathbb{Z}}c(k-s)e^{-i\xi (k-s)}d(s) e^{-i\xi s}=\\
\sum_{s \in \mathbb{Z}}\sum_{k\in\mathbb{Z}}c(k-s)e^{-i\xi (k-s)}d(s) e^{-i\xi s}=\\
\sum_{s \in \mathbb{Z}}d(s) e^{-i\xi s}\sum_{k\in\mathbb{Z}}c(k-s)e^{-i\xi (k-s)}\\
\kappa\colonequals k-s;\\
\sum_{s \in \mathbb{Z}}d(s) e^{-i\xi s}\sum_{\kappa\in\mathbb{Z}}c(\kappa)e^{-i\xi \kappa}=\\
\sum_{\kappa\in\mathbb{Z}}c(\kappa)e^{-i\xi \kappa}\sum_{s \in \mathbb{Z}}d(s) e^{-i\xi s}=\\
\widehat{c}(\xi)\widehat{d}(\xi)
&lt;/script&gt;
&lt;h2 id=&quot;what-s-a-filter&quot;&gt;What&#39;s a Filter?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-s-a-filter&quot; aria-label=&quot;Anchor link for: what-s-a-filter&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A filter is just a vector of some length N (or function on some interval), where we interpret the values as coefficients of the filter. The vector of filter coefficients will be called a &quot;filter window&quot; from here on.&lt;/p&gt;
&lt;p&gt;Filtering a signal can be achieved like this:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;for each sample:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    place the window on the signal, such that the sample is at the window center&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    for each value of the window:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        multiply the value with the corresponding signal sample&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        add the result to an accumulator A&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    set the value of the center sample to the value of A&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(This explanation is probably very engineer-like and insufficient for mathematicians. What can I do.)&lt;/p&gt;
&lt;p&gt;A simple example: set all values of the filter to&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;1/N&lt;/script&gt;
&lt;p&gt;. Then a sample in a filtered signal is the arithmetic mean of the samples around it, removing high-frequency content.&lt;/p&gt;
&lt;h2 id=&quot;properties-of-filters&quot;&gt;Properties of Filters&lt;a class=&quot;zola-anchor&quot; href=&quot;#properties-of-filters&quot; aria-label=&quot;Anchor link for: properties-of-filters&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Notice the filter coefficients in the previous example where&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;1/N&lt;/script&gt;
&lt;p&gt;. Otherwise, we might modify the energy of the signal. Obviously, you don&#39;t want a filtered signal to be amplified or diminished. This kind of filter is called &quot;Energy-Preserving&quot;.&lt;/p&gt;
&lt;p&gt;There are many more properties, one of which is linearity. A linear filter has the property that you can apply it to a sum of signals and get the same result as applying it to each  signal individually and then summing the result. Put in another way:&lt;/p&gt;
&lt;p&gt;Let&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;c, d \in l_2(\mathbb{Z})&lt;/script&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;a, b \in \mathbb{R}&lt;/script&gt;
&lt;p&gt;. Then:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
F(ac+bd) = aFc + bFd
&lt;/script&gt;
&lt;p&gt;This property will become important later.&lt;/p&gt;
&lt;h2 id=&quot;the-unit-impulse-and-why-it-is-important&quot;&gt;The Unit Impulse and why it is important&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-unit-impulse-and-why-it-is-important&quot; aria-label=&quot;Anchor link for: the-unit-impulse-and-why-it-is-important&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The Unit Impulse function (or dirac delta) is... not actually a function, but a distribution. However, we will treat it as the following function here:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\delta(t) =
\begin{cases}
0,  &amp; t \lt 0 \\
1,  &amp; t = 0 \\
0,  &amp; t \gt 0
\end{cases}
&lt;/script&gt;
&lt;p&gt;The impulse contains frequencies from every wavelength with the same amplitude.
Intuitively, it is a &quot;bang&quot;, like a gunshot. It&#39;s Fourier Transform is... just&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;1&lt;/script&gt;
&lt;p&gt;:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
\widehat{\delta}(\xi) = \int_{-\infty}^{\infty}\delta (t)e^{-i\xi t}dt = 1
&lt;/script&gt;
&lt;p&gt;In other words, we can get a unit impulse by summing up cosines of ever-increasing frequency.
So what happens if we apply a filter to a unit impulse?
Well, by the linearity property stated above, that would be the same as applying the filter to each of the frequencies the unit impulse is comprised of - which is, all of them.
You read that right - with the unit impulse, we can see what a filter does to ANY frequency.
Does it diminish high frequency? Only the low frequencies from the impulse get through.
Is there a band that the filter attenuates? Those frequencies will be dimmed in the result. By the way, the result of applying a filter to a unit impulse is aptly called the &quot;Impulse Response&quot;.&lt;/p&gt;
&lt;p&gt;Now, let&#39;s think about the Fourier Transform of an impulse response.
The impulse response contains every frequency with the amplitude that the filter permits for this frequency.
So it&#39;s spectral content directly displays how the filter behaves for a given frequency.&lt;/p&gt;
&lt;p&gt;I will denote the impulse response&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;F\delta&lt;/script&gt;
&lt;p&gt;of a filter&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;F&lt;/script&gt;
&lt;p&gt;with&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;f&lt;/script&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;h2 id=&quot;convolution-and-filter-application&quot;&gt;Convolution and Filter Application&lt;a class=&quot;zola-anchor&quot; href=&quot;#convolution-and-filter-application&quot; aria-label=&quot;Anchor link for: convolution-and-filter-application&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now let&#39;s clarify why applying filters can be achieved by Convolution. The best explanation I found is rather mathematical, but somewhat easy to understand.&lt;/p&gt;
&lt;p&gt;First, let&#39;s look at a signal&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;c&lt;/script&gt;
&lt;p&gt;in a slightly contrived way:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
c(\cdot) = \sum_{k \in \mathbb{Z}}c(k)\delta(\cdot-k)
&lt;/script&gt;
&lt;p&gt;Equivalently, where&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;\tau_{s}c(\cdot) = c(\cdot + s)&lt;/script&gt;
&lt;p&gt;:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
c(\cdot) = \sum_{k \in \mathbb{Z}}c(k)\tau_{-k}\delta
&lt;/script&gt;
&lt;p&gt;Which is to say: you can picture a signal at a point as a unit impulse shifted to exactly that point multiplied with the entire signal.&lt;/p&gt;
&lt;p&gt;Now let&#39;s see what happens if we apply a filter&lt;/p&gt;
&lt;script type=&quot;math/tex&quot;&gt;F&lt;/script&gt;
&lt;p&gt;to that signal and simplify the result.&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
Fc(\cdot) = F\Big[\sum_{k \in \mathbb{Z}}c(k)\tau_{-k}\delta\Big] = \\
\sum_{k \in \mathbb{Z}}c(k)F[\tau_{-k}\delta] = \\
\sum_{k \in \mathbb{Z}}c(k)\tau_{-k}F\delta = \\
\sum_{k \in \mathbb{Z}}c(k)\tau_{-k}f = \\
\sum_{k \in \mathbb{Z}}c(k)f(\cdot - k) = \\
(c \ast f)(\cdot)
&lt;/script&gt;
&lt;p&gt;And there you have it! Applying a filter to a signal is the same as multiplying the transformed signal with the transfer function and taking the inverse Fourier Transform of the result:&lt;/p&gt;
&lt;script type=&quot;math/tex;mode=display&quot;&gt;
Fc(t) = (c \ast f)(t) = (\hat{c}\hat{f})\vee(t)
&lt;/script&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Statements and Expressions in Rust</title>
        <published>2018-06-16T00:00:00+00:00</published>
        <updated>2018-06-16T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/statements-and-expressions-in-rust/"/>
        <id>https://barafael.github.io/posts/statements-and-expressions-in-rust/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/statements-and-expressions-in-rust/">&lt;p&gt;In this post, we will explore how Rust distinguishes between expressions and statements.
Even though this distinction seems very theoretical, it has wide-ranging implications on the Rust language and (in my opinion) is a beautiful detail of Rust.&lt;/p&gt;
&lt;h2 id=&quot;terms-and-conditions&quot;&gt;Terms and Conditions&lt;a class=&quot;zola-anchor&quot; href=&quot;#terms-and-conditions&quot; aria-label=&quot;Anchor link for: terms-and-conditions&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;What do I mean by expressions and statements?&lt;/p&gt;
&lt;p&gt;Arithmetic terms like &lt;code&gt;(a + 3) / 2&lt;/code&gt;, or a condition &lt;code&gt;(a &amp;amp; !b) | (!a &amp;amp; b)&lt;/code&gt; are expressions. Evaluating them yields some (non-empty-)value like &lt;code&gt;3&lt;/code&gt; or &lt;code&gt;true&lt;/code&gt;. This is what functional programmers mean when they say their whole program is basically one large mathematical term which is evaluated. It is important to note that evaluating an expression in this mode of thinking has no effect on the outside world, or &#39;context&#39;.&lt;/p&gt;
&lt;p&gt;To interact with the world, we need statements. A statement could be &lt;code&gt;motor.drive(100)&lt;/code&gt;, where &lt;code&gt;drive(int)&lt;/code&gt; is a void function which changes the context such that something in the real world reflects this effect (like writing to an output port).&lt;/p&gt;
&lt;h2 id=&quot;what-s-in-a-block&quot;&gt;What&#39;s in a &#39;{}&#39;-Block?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-s-in-a-block&quot; aria-label=&quot;Anchor link for: what-s-in-a-block&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Languages like C and Java use curly braces to denote scope. In Rust, curly braces mark a scope too, but they can also evaluate to a value. This value can be empty &#39;()&#39;, though. Let&#39;s see some examples:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Standard C if statement&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;some_condition&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    some_action&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Slightly different syntax for Rust&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; some_condition&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    some_action&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The syntax appears very similar, but this is a false lookalike: we can evaluate expressions in blocks.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; if&lt;/span&gt;&lt;span&gt; some_condition&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    some_action&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a very structured solution to the frequent problem of conditionally assigning/binding values to variables.&lt;/p&gt;
&lt;p&gt;It should be noted that a semicolon suppresses the value of an expression. This is why we do not have semicola after &lt;code&gt;3&lt;/code&gt; or &lt;code&gt;some_action()&lt;/code&gt;, but after the last curly brace.&lt;/p&gt;
&lt;h3 id=&quot;retiring-the-ternary-operator&quot;&gt;Retiring the Ternary Operator&lt;a class=&quot;zola-anchor&quot; href=&quot;#retiring-the-ternary-operator&quot; aria-label=&quot;Anchor link for: retiring-the-ternary-operator&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This C shorthand for an if-else-block as expression:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; val &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 5&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; result &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span&gt; val &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 10&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ?&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 10&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; :&lt;/span&gt;&lt;span&gt; val&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;does not require special syntax in Rust.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; val&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 5&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; if&lt;/span&gt;&lt;span&gt; val&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 10&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 10&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; val&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that in the Rust snippet, each branch of the if statement evaluates to a number.&lt;/p&gt;
&lt;h2 id=&quot;the-point-of-no-return&quot;&gt;The Point of &#39;No Return&#39;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-point-of-no-return&quot; aria-label=&quot;Anchor link for: the-point-of-no-return&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using the &lt;code&gt;return&lt;/code&gt; keyword is discouraged sometimes in the Rust community. It makes no difference for the program, but omitting it fits better with the &#39;Everything is an Expression&#39; mode of thinking. This becomes apparent when looking at the following examples, which may look scary for some C programmers.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; C function that simply returns some value&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; some_function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; x&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The exit point of a C function often is a &#39;return&#39;, reminding us that in the background, the stack is restored and control is given to the caller.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; In Rust, the &amp;#39;return&amp;#39; is unnecessary, since the function body is an expression.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; some_function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    x&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; A void function in Rust&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Note: function actually returns &amp;#39;()&amp;#39;, which is value of expression &amp;#39;x + 3;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; some_void_func&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    x&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; &amp;lt; note the semicolon&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Note: the &amp;#39;return&amp;#39; keyword can still be used for early returns&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; early_return&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;num&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u8&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u8&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; num&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;unary-incr-decrement-confusion&quot;&gt;Unary incr/decrement Confusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#unary-incr-decrement-confusion&quot; aria-label=&quot;Anchor link for: unary-incr-decrement-confusion&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The standard way to increment a variable in C:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; x &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Both expression (evaluates to 10) and statement (increments x).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Same here, except expression evaluates to 12 now.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;++&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Rust, this works differently:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;x++ // not possible&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This prevents such C chaos:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; c &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; What does this evaluate to?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; d &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ++&lt;/span&gt;&lt;span&gt;c &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; and this?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; e &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ++&lt;/span&gt;&lt;span&gt;c &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;switch-case-is-no-match-for-patterns&quot;&gt;Switch-Case is no Match for Patterns&lt;a class=&quot;zola-anchor&quot; href=&quot;#switch-case-is-no-match-for-patterns&quot; aria-label=&quot;Anchor link for: switch-case-is-no-match-for-patterns&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pattern matching in Rust takes advantage of expression blocks quite beautifully:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; choice&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 17&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; is_sparta&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;let&lt;/span&gt;&lt;span&gt; result&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; match&lt;/span&gt;&lt;span&gt; choice&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    0&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;zero for u&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;choice not great&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    i&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; if&lt;/span&gt;&lt;span&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; %&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;larger than or equal 11, and odd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    42&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;u r n4rd&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    300&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        if&lt;/span&gt;&lt;span&gt; is_sparta&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;            &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;This is Sparta!&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;            &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;This is not Sparta!&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;larger than or equal 10, and even&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; &amp;lt; semicolon needed, because this expression binds to &amp;#39;result&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every match arm must evaluate to the same type (&amp;amp;str here). The match arm can be any expression in a block that eventually evaluates to a &amp;amp;str.
The patterns must be exhaustive!
This is like switch/case on steroids.&lt;/p&gt;
&lt;h2 id=&quot;let-s-if-let&quot;&gt;Let&#39;s if let&lt;a class=&quot;zola-anchor&quot; href=&quot;#let-s-if-let&quot; aria-label=&quot;Anchor link for: let-s-if-let&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To destructure enums using &lt;code&gt;if let&lt;/code&gt; is useful for ergonomic error handling with algebraic error types(Option, Result):&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; number&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Option&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;i32&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;8&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; let&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;8&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; number&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Option contained an eight!&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; let&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Some&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; number&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Matched &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;:?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Option contained None!&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works with any pattern, on enums, structs, and tuples.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How the Rust Compiler prevents mistakes</title>
        <published>2018-06-04T00:00:00+00:00</published>
        <updated>2018-06-04T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/how-the-rust-compiler-prevents-mistakes/"/>
        <id>https://barafael.github.io/posts/how-the-rust-compiler-prevents-mistakes/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/how-the-rust-compiler-prevents-mistakes/">&lt;p&gt;When learning about Rust for the first time, one is confronted with words like &#39;double free&#39;, &#39;data race&#39;, and &#39;dangling pointer&#39;.
Without an understanding of these problems, the safety aspects of Rust are perhaps difficult to appreciate.
However, Rust aims to appeal not only to systems programmers(where these kinds of problems are well-known), but developers from any background! It is perfectly fine to write high-level Rust code without knowing what a data race is (that is the freedom Rust grants) but understanding the underlying issue makes the compiler error messages more understandable.&lt;/p&gt;
&lt;p&gt;To explain some of the problems Rust solves, I have collected examples to show and explain specific problems and see what &lt;code&gt;rustc&lt;/code&gt;(&quot;the Rust complainer&quot;) has to say about them.&lt;/p&gt;
&lt;h2 id=&quot;let-s-start-simple-dereferencing-null-pointers&quot;&gt;Let&#39;s start simple: Dereferencing Null Pointers&lt;a class=&quot;zola-anchor&quot; href=&quot;#let-s-start-simple-dereferencing-null-pointers&quot; aria-label=&quot;Anchor link for: let-s-start-simple-dereferencing-null-pointers&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When Tony Hoare finished implementing ALGOL 60 in 1965, he couldn&#39;t know that he would be apologizing for one of its concepts 44 years later: at &#39;09 QCon in London, he called null pointers a &#39;billion dollar mistake.&#39;&lt;/p&gt;
&lt;p&gt;Languages since have picked up variations of the concept. For example, Java has no pointers accessible to the programmer, yet it has a &lt;code&gt;NullPointerException&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&#39;s look at a simple C example of a null pointer dereference:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;stdio.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Reading and writing to a NULL pointer results in undefined behavior.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    int&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span&gt;ptr &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    *&lt;/span&gt;&lt;span&gt;ptr     &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span&gt;ptr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We create a pointer to an int with the value of &lt;code&gt;NULL&lt;/code&gt;. When we try to write to that location, a SIGSEGV happens to happen on my machine and setup, but dereferencing a NULL pointer is undefined behavior, meaning that anything could happen.&lt;/p&gt;
&lt;p&gt;How does this look in Rust? Simply put, safe Rust has no null references. There is no way to express this in safe Rust.&lt;/p&gt;
&lt;p&gt;There is always &lt;code&gt;unsafe&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span&gt;ptr&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; pointer&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;mut&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u32&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; ptr&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;null_mut&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        *&lt;/span&gt;&lt;span&gt;pointer&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    unsafe&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span&gt;pointer&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this code, I happen to get a SIGSEGV, too.&lt;/p&gt;
&lt;h2 id=&quot;and-now-for-something-more-interesting-free-of-use-after-free&quot;&gt;And now for something more interesting: Free of &#39;use-after-free&#39;&lt;a class=&quot;zola-anchor&quot; href=&quot;#and-now-for-something-more-interesting-free-of-use-after-free&quot; aria-label=&quot;Anchor link for: and-now-for-something-more-interesting-free-of-use-after-free&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Unlike many other languages, we have to explicitly request and release our memory from/to the operating system when working with C.
Those actions still happen when using Java, Python, or Haskell, but they happen automatically in the background. This is safe (because it is automatic), and it is very comfortable for the programmer. However, such garbage collection has a cost, which is out of scope for this article but frequently discussed.&lt;/p&gt;
&lt;p&gt;Managing memory manually (like it is done in most systems programming languages) is a difficult problem because we have to ensure that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;all allocated memory is &lt;code&gt;free()&lt;/code&gt;&#39;d (no memory leaks)&lt;/li&gt;
&lt;li&gt;memory that was &lt;code&gt;free()&lt;/code&gt;&#39;d before is never reused (no use-after-free)&lt;/li&gt;
&lt;li&gt;memory is &lt;code&gt;free()&lt;/code&gt;&#39;d exactly once in all code paths of the program (no double free)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If we fail to do this, our program might crash, or worse, it might corrupt data anywhere or present opportunities to attackers.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;free&lt;/code&gt; function in C deallocates previously allocated blocks of memory, but it does not invalidate our pointer to that memory - we can still use it:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;stdio.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;stdlib.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; BUF_SIZE&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 16&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    puts&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Enter your name!&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    char&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span&gt;buffer &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BUF_SIZE&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    fgets&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; BUF_SIZE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; stdin&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;buffer: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buffer&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    free&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; reusing dangling pointer into heap&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    fgets&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; BUF_SIZE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; stdin&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;buffer after free: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buffer&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We allocate a 16-byte block, which we then pass to the &lt;code&gt;fgets&lt;/code&gt; function to read user input. After printing that input, we free the buffer.
Nothing in the C language stops us from using that pointer again!&lt;/p&gt;
&lt;p&gt;Let&#39;s see what this would look like in Rust:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;BufRead&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Enter your name!&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; stdin&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;stdin&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; buffer&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; stdin&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;lock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;lines&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;next&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;unwrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    drop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;buffer: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buffer&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All the Rust compiler has to say is:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;error[E0382]: use of moved value: `buffer`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  --&amp;gt; use_after_free.rs:10:28&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8  |     drop(buffer);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   |                    ------ value moved here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;9  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 |     println!(&amp;quot;buffer: {}&amp;quot;, buffer);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   |                            ^^^^^^ value used here after move&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   = note: move occurs because `buffer` has type `std::string::String`, which does not implement the `Copy` trait&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The error message uses some Rust-specific language (move? Copy trait?), but it is pretty clear: ownership of the buffer is moved into &lt;code&gt;drop()&lt;/code&gt;, after which the buffer is not usable.&lt;/p&gt;
&lt;p&gt;It is important to note that the &lt;code&gt;drop&lt;/code&gt; function is used rarely in Rust. That is because every object is destructed automatically at the point where its owner&#39;s scope ends (which is known at compile time).&lt;/p&gt;
&lt;p&gt;Regardless, the function exists, and it is one of the most beautiful functions in the standard library:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;pub&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; drop&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;T&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_x&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s all they wrote: take ownership of an &lt;code&gt;_x&lt;/code&gt; of an unconstrained type T, and go out of scope, resulting in the deterministic deconstruction of &lt;code&gt;_x&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;but-what-about-std-move&quot;&gt;But what about &lt;code&gt;std::move&lt;/code&gt;?&lt;a class=&quot;zola-anchor&quot; href=&quot;#but-what-about-std-move&quot; aria-label=&quot;Anchor link for: but-what-about-std-move&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Modern C++ introduced moving ownership. The move constructor invalidates the old owner in some agreed-upon way, even if the object is const. After the move, the old pointer may still be used (but that is not a good idea!).&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;iostream&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;using&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; namespace&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    string&lt;/span&gt;&lt;span&gt; origin&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;This is a string.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    vector&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;string&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Copy origin and append to vec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vec&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;push_back&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;origin&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cout&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;After pushing origin copy onto vec, origin is unchanged: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; origin&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Move origin into vec, invalidating origin variable (at runtime)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vec&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;push_back&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;move&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;origin&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cout&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;After move into vec, origin is invalidated: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; origin&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cout&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Contents of vec: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; vec&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that a moved-from object (that is not trivially destructible) still has to be destroyed: http://www.drdobbs.com/cpp/why-moving-an-object-does-not-destroy-th/231601451&lt;/p&gt;
&lt;p&gt;Rust has moves and ownership baked deep into the language:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; origin&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; String&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;This is a string&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; moved&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; origin&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;origin after move: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; origin&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;moved  after move: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; moved&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Binding that was moved out from can be reassigned&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    origin&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Hello, I&amp;#39;m back!&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;into&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;origin after reassignment: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; origin&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Rust compiler comments:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;error[E0382]: use of moved value: `origin`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; --&amp;gt; use_after_move_var.rs:6:39&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4 |     let moved = origin;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |         ----- value moved here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6 |     println!(&amp;quot;origin after move: {}&amp;quot;, origin);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |                                       ^^^^^^ value used here after move&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  = note: move occurs because `origin` has type `std::string::String`, which does not implement the `Copy` trait&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Types implementing the &lt;code&gt;Copy&lt;/code&gt;-trait are similar to &#39;primitive datatypes&#39; in java. They are passed by value (or &#39;by copy&#39;).
But copying is a quick operation only for a few basic types! For any other type, the explicit &lt;code&gt;clone&lt;/code&gt; method can be used, if the type implements the &lt;code&gt;Clone&lt;/code&gt; trait. This is unlike C++, where an implicit copy of an object often occurs, without any special syntax.&lt;/p&gt;
&lt;h1 id=&quot;the-many-kinds-of-dangling-pointers&quot;&gt;The Many Kinds Of Dangling Pointers&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-many-kinds-of-dangling-pointers&quot; aria-label=&quot;Anchor link for: the-many-kinds-of-dangling-pointers&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;h3 id=&quot;dangling-pointer-into-heap&quot;&gt;Dangling Pointer Into Heap&lt;a class=&quot;zola-anchor&quot; href=&quot;#dangling-pointer-into-heap&quot; aria-label=&quot;Anchor link for: dangling-pointer-into-heap&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In C-like languages, we can use the addresses of objects on the heap or stack directly. This is powerful, but it means we have to be cautious about the memory at the other end of a pointer:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;stdlib.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;stdio.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; BUFFER_SIZE&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 16&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    int&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span&gt;array &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BUFFER_SIZE &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;size_t&lt;/span&gt;&lt;span&gt; index &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; index &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; BUFFER_SIZE&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; index&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;++&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;        array&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;index&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; index&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Take a pointer into the heap-allocated array&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    int&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span&gt;ptr &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;array&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;6&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; at this point, ptr becomes a dangling pointer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    free&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;array&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;#39;s array has been set free!&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span&gt;ptr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    *&lt;/span&gt;&lt;span&gt;ptr &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;array[6] was modified to &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; after being free&amp;#39;d!&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span&gt;ptr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This program allocates a buffer on the heap, creates a pointer into that buffer, then frees the buffer. However, the pointer still exists! That is a dangling pointer into the heap. Let&#39;s reconstruct this in Rust:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; array&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Vec&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    for&lt;/span&gt;&lt;span&gt; index&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;10&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        array&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;index&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; as&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Take a pointer into the heap-allocated array&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; reference&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;mut&lt;/span&gt;&lt;span&gt; array&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;6&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; at this point, reference would become a dangling pointer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    drop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;array&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;#39;s array has been set free!&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span&gt;reference&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    *&lt;/span&gt;&lt;span&gt;reference&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;array[6] was modified to &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; after being free&amp;#39;d!&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span&gt;reference&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The compiler interjects! Error message:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;error[E0505]: cannot move out of `array` because it is borrowed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  --&amp;gt; dangling_pointer_heap.rs:11:20&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;8  |     let reference = &amp;amp;mut array[6];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   |                          ----- borrow of `array` occurs here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;11 |     drop(array);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   |                    ^^^^^ move out of `array` occurs here&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The message is clear. How dare we move the ownership of the variable array to &lt;code&gt;drop&lt;/code&gt; if we still have borrowed it to &lt;code&gt;reference&lt;/code&gt;?&lt;/p&gt;
&lt;h1 id=&quot;capturing-closures&quot;&gt;Capturing Closures&lt;a class=&quot;zola-anchor&quot; href=&quot;#capturing-closures&quot; aria-label=&quot;Anchor link for: capturing-closures&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Closures are anonymous functions which can capture variables from their originating scope.
Therefore, if we create a string variable &lt;code&gt;some_string&lt;/code&gt; and a closure &lt;code&gt;some_closure&lt;/code&gt; in one scope, we can use &lt;code&gt;some_string&lt;/code&gt; from &lt;code&gt;some_closure&lt;/code&gt;.
Closures would be pointless if we could not pass them around different scopes! That is dangerous, though:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;iostream&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;functional&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;using&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; namespace&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;function&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; get_lambda_with_local_reference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; index&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    int&lt;/span&gt;&lt;span&gt; local_arr&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 4&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 5&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; return&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span&gt; local_arr&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;index&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; This function returns a lambda which internally keeps a pointer to a local array.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Of course, when using the returned lambda, the array does not exist anymore.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    function&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; get_lambda_with_local_reference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cout&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;lambda uses stack-local reference:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;6&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; endl&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The function &lt;code&gt;get_lambda_with_local_reference&lt;/code&gt; will return a &lt;code&gt;function&amp;lt;int(int)&amp;gt;&lt;/code&gt;, which is a lambda that takes and returns an int.
That function is defined in the last line of &lt;code&gt;get_lambda_with_local_reference&lt;/code&gt; as returning the sum of its argument and the element at index &lt;code&gt;index&lt;/code&gt; of an array defined in the same (stack frame) scope.
When we return the lambda, this array goes out of scope. When we call it, the lambda dereferences some random value from the stack (at best).&lt;/p&gt;
&lt;p&gt;Same story in Rust:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; This function returns a closure with a pointer to a stack-local array.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; get_lambda_with_local_reference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;index&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; usize&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; impl&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Fn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;i32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; i32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; local_arr&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    |&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span&gt; local_arr&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;index&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Moving the stack-local array into the returned closure is fine.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; get_lambda_with_moved_reference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;index&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; usize&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; impl&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Fn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;i32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; i32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; local_arr&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    move&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; |&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span&gt; local_arr&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;index&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; function&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; get_lambda_with_local_reference&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;lambda uses stack-local reference: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;6&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Rust Complainer says NO:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;error[E0373]: closure may outlive the current function, but it borrows `local_arr`, which is owned by the current function&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; --&amp;gt; dangling_pointer_closure.rs:5:5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 |     |value| value + local_arr[index]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |     ^^^^^^^         --------- `local_arr` is borrowed here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |     |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |     may outlive borrowed value `local_arr`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;help: to force the closure to take ownership of `local_arr` (and any other referenced variables), use the `move` keyword&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5 |     move |value| value + local_arr[index]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  |     ^^^^^^^^^^^^&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;rustc&lt;/code&gt; also suggests how to fix the problem, as seen in the function &lt;code&gt;get_lambda_with_moved_reference&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;more-dangling-pointers&quot;&gt;More dangling pointers&lt;a class=&quot;zola-anchor&quot; href=&quot;#more-dangling-pointers&quot; aria-label=&quot;Anchor link for: more-dangling-pointers&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can find more examples of less interesting dangling pointers &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/errare-humanum-est/tree/master/examples&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;crossing-boundaries-or-yet-another-billion-dollar-mistake&quot;&gt;Crossing Boundaries or: yet another &#39;Billion Dollar Mistake&#39;&lt;a class=&quot;zola-anchor&quot; href=&quot;#crossing-boundaries-or-yet-another-billion-dollar-mistake&quot; aria-label=&quot;Anchor link for: crossing-boundaries-or-yet-another-billion-dollar-mistake&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;For performance reasons, the creators of the C language used raw pointers to memory blocks as array types. After creating an array, it&#39;s size has to be tracked manually, often by something like &lt;code&gt;#define BUF_SIZE 256&lt;/code&gt;. Array access by index, like &lt;code&gt;arr[115]&lt;/code&gt;, happens without checking bounds. One could check manually.
Similarly, strings (which are just char pointers) always end with a &lt;code&gt;\0&lt;/code&gt;-byte. The performance benefits come with a price - it is incredibly easy to make a mistake:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; BUFFER_SIZE&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 15&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;/*&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Compile with -fno-stack-protector for real fun &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    int&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; buffer&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;BUFFER_SIZE&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; index &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; index &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span&gt; BUFFER_SIZE&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; index&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;++&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;        buffer&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;index&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; index&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; or equivalently, but more explicit:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buffer &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span&gt; index&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; index&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just one character too much - the &#39;=&#39; in the for loop exit condition causes our index to reach one element past the buffer boundaries.
This is easy to catch. But there are other possible buffer overruns which are even in the C library:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;stdio.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;string.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; BUFFER_SIZE&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 16&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;/*&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Compile with -fno-stack-protector for full effect &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; gets is a hazardous function, and gcc even warns when using it.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Here, gets overwrites a part of the stack when a long text is entered on stdin,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; possibly corrupting a variable that comes after the input buffer on the stack.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; buffer&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;BUFFER_SIZE&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    int&lt;/span&gt;&lt;span&gt; password &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Enter password:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    gets&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;strcmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;pass123&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Correct password&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        password &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Wrong password&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;password&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Privileged access granted!!!&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Writing a string into the buffer that is larger than the buffer can corrupt the password flag and grant us privileged access!
And yes, you should not use &lt;code&gt;gets&lt;/code&gt;, as the compiler may tell us here. So, let&#39;s use fgets, but hide a mistake in our code:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;stdio.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;string.h&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; BUFFER_SIZE&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 16&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;/*&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Compile with -fno-stack-protector &lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;*/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; fgets is somewhat better than gets. But one can still use it wrong.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; buffer&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;BUFFER_SIZE &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 5&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    int&lt;/span&gt;&lt;span&gt; password &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Enter password:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    fgets&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; BUFFER_SIZE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; stdin&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;strcmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;pass123&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Correct password&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        password &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Wrong password&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;password&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Privileged access granted!!!&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fundamental problem is that the array size is unknown. There may be a performance advantage to not having those runtime index bounds checks, but modern LLVM is good at optimizing those away. Either way, bounds checks should be an opt-out feature for critical loops, not an opt-in by manually coding them in my opinion.&lt;/p&gt;
&lt;p&gt;Obligatory Rust example:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; BufRead&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; array&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 4&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 5&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 7&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 9&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    for&lt;/span&gt;&lt;span&gt; index&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;10&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; array&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;index&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code panics with &#39;index out of bounds&#39; at runtime. Rust cannot catch that kind of bug at compile time (it is hard to catch in the general case)!&lt;/p&gt;
&lt;h1 id=&quot;the-real-fun-stuff-access-to-shared-data&quot;&gt;The Real Fun Stuff: Access to Shared Data&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-real-fun-stuff-access-to-shared-data&quot; aria-label=&quot;Anchor link for: the-real-fun-stuff-access-to-shared-data&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Data races can happen if these 3 conditions are met: (1) multiple parts of a program have access to the same memory (sharing), (2) at least one of them writes to the shared data (mutation), and (3) there is no mechanism in place to ensure proper order of transactions (synchronization).&lt;/p&gt;
&lt;p&gt;To wrap everything in mutexes and semaphores is one viable option, but Rust offers a safer and faster option: ensuring the first 2 conditions are never true at the same time. This is what &quot;Sharing XOR mutation&quot; means: either many processes read, or at most one writes. It turns out the borrow checker that ensures memory errors never happen also prevents many issues arising from shared access to resources because there is always a clear owner and it is known if and how data is shared.&lt;/p&gt;
&lt;p&gt;Here is what a multithreaded C++ program could look like:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;iostream&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Account&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    int&lt;/span&gt;&lt;span&gt; balance&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 100&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; transferMoney&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; amount&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Account&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;from&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Account&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;to&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    using&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; namespace&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;chrono_literals&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;balance&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;gt;=&lt;/span&gt;&lt;span&gt; amount&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        from&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;balance&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -=&lt;/span&gt;&lt;span&gt; amount&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;this_thread&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;sleep_for&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;ns&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        to&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;balance&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +=&lt;/span&gt;&lt;span&gt; amount&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; printSum&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Account&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;a2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;cout&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;a1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;balance&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span&gt; a2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;balance&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;endl&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    Account&lt;/span&gt;&lt;span&gt;     account1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    Account&lt;/span&gt;&lt;span&gt;     account2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; thr1&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;transferMoney&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 50&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;ref&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;account1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;ref&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;account2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; thr2&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;transferMoney&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 130&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;ref&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;account2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;ref&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;account1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    thr1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;join&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    thr2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;join&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;cout&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;account1.balance: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; account1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;balance&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;endl&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;cout&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;account2.balance: &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; account2&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;balance&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;endl&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;cout&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;endl&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We give the data race some time to occur. What happens is not deterministic, but the second transaction is sometimes just swallowed by the void.
We have met all 3 of the above conditions!&lt;/p&gt;
&lt;p&gt;To fix the problem, we might use an &lt;code&gt;atomic&lt;/code&gt; type for &lt;code&gt;balance&lt;/code&gt;, however, not even cppcheck or clang-tidy warn us here.&lt;/p&gt;
&lt;p&gt;Translating the same to Rust:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;derive&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Debug&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Account&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    balance&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Account&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; transfer_money_to&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;mut&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; self&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; amount&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Account&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        if&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;balance &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span&gt; amount&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;            self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;balance &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;-=&lt;/span&gt;&lt;span&gt; amount&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            std&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;sleep&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Duration&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;from_millis&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            to&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span&gt;balance &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+=&lt;/span&gt;&lt;span&gt; amount&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;initial&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; u32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; Self&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        Account&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            balance&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;:&lt;/span&gt;&lt;span&gt; initial&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; account1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Account&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;100&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; mut&lt;/span&gt;&lt;span&gt; account2&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Account&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;100&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; child1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;spawn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        account1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;transfer_money_to&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;50&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; account2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    let&lt;/span&gt;&lt;span&gt; child2&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;thread&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;spawn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        account2&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;transfer_money_to&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;130&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; account1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    child1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;join&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    child2&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;join&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    println!&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;:?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;:?&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; account1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; account2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The error message here is quite long because there are so many mistakes from the Rust compiler&#39;s point of view.&lt;/p&gt;
&lt;h1 id=&quot;more-examples&quot;&gt;More examples&lt;a class=&quot;zola-anchor&quot; href=&quot;#more-examples&quot; aria-label=&quot;Anchor link for: more-examples&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A few more examples can be found &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/errare-humanum-est/tree/master/examples&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;a-solution-for-c-and-c-great-linters&quot;&gt;A solution for C and C++: great linters&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-solution-for-c-and-c-great-linters&quot; aria-label=&quot;Anchor link for: a-solution-for-c-and-c-great-linters&quot;&gt;🔗&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The &lt;code&gt;cppcheck&lt;/code&gt; and &lt;code&gt;clang-tidy&lt;/code&gt; have heuristics for many of the problems listed here. Often, their explanation of the problem is excellent, as well.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Object-Oriented Arduino interrupts: using C++ Friend Functions</title>
        <published>2018-01-07T00:00:00+00:00</published>
        <updated>2018-01-07T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/object-oriented-arduino-interrupts-using-c-friend-functions/"/>
        <id>https://barafael.github.io/posts/object-oriented-arduino-interrupts-using-c-friend-functions/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/object-oriented-arduino-interrupts-using-c-friend-functions/">&lt;p&gt;Most Arduino users won&#39;t ever need interrupts or even C++/OOP for that matter.
But for writing a nice object-oriented library or advancing your programming
skills, both are very interesting subjects. But they clash somewhat: an
interrupt is basically a global function that takes no arguments (not even
C++-&lt;code&gt;this&lt;/code&gt;) and returns no value, either. It is not called by the main
program like regular functions, but instead runs when it is triggered by an
external signal, like a pin logic voltage level change. This idea has no place
in an OOP (let alone functional!) world - what object does the function belong
to? It is global and cannot see or modify anything but static data, and the
fact that it does not take arguments makes it impossible to call this function
with method syntax. If this is confusing, don&#39;t worry: in C++, a function knows
which object it belongs to by the implicit, invisible argument &lt;code&gt;this&lt;/code&gt;. If
it is still confusing, don&#39;t worry - it doesn&#39;t really matter. It just means
that interrupts and OOP do not mix well.&lt;/p&gt;
&lt;p&gt;Unless...&lt;/p&gt;
&lt;h2 id=&quot;c-friend-functions&quot;&gt;C++ Friend Functions&lt;a class=&quot;zola-anchor&quot; href=&quot;#c-friend-functions&quot; aria-label=&quot;Anchor link for: c-friend-functions&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A Friend Function is a function that can be at global scope (i.e. not belonging
to a class) but still retain private access to all members of a specified class
as if it was a member of that class. This class has to declare the function as
a friend. Now, this function can be registered as interrupt!&lt;/p&gt;
&lt;p&gt;There is one tiny ugly thing that remains: to access private members of a class instance, this instance has to be known by the interrupt. This can be done by having a global pointer to a class instance which is valid for the lifetime of the instance. If you attach your interrupts and set this pointer in your constructor you should be fine. Remember to detach the interrupts and set the pointer to &lt;code&gt;NULL&lt;/code&gt; or &lt;code&gt;nullptr&lt;/code&gt; in the destructor, if this applies to your program.&lt;/p&gt;
&lt;h2 id=&quot;example-code-simple-library-to-interface-an-arduino-or-teensy-device-to-an-rc-receiver&quot;&gt;Example Code: Simple library to interface an Arduino or Teensy device to an RC Receiver&lt;a class=&quot;zola-anchor&quot; href=&quot;#example-code-simple-library-to-interface-an-arduino-or-teensy-device-to-an-rc-receiver&quot; aria-label=&quot;Anchor link for: example-code-simple-library-to-interface-an-arduino-or-teensy-device-to-an-rc-receiver&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is the code:&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/barafael/7434737e6c1846a9107b87213ea14a09.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;For a possibly more up-to-date version: &lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/RC-Receiver-Interface/&quot;&gt;github repo.&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Programming the Teensy 3.2 using a makefile</title>
        <published>2017-11-21T00:00:00+00:00</published>
        <updated>2017-11-21T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/programming-the-teensy-3-2-using-a-makefile/"/>
        <id>https://barafael.github.io/posts/programming-the-teensy-3-2-using-a-makefile/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/programming-the-teensy-3-2-using-a-makefile/">&lt;p&gt;The Arduino toolchain is a good starting point. So many libraries, most of them
fine quality, and the editor allows you to write incorrect C++ so you can have
a simpler life...&lt;/p&gt;
&lt;p&gt;Wait, what? That&#39;s right, the Arduino IDE does a lot of stuff to compile your
program that usually does not happen in the standard C++ compilation procedure.
For example, the IDE generates function prototypes for you, so that you can
write your functions in whichever order you like. This alone is iffy for some.
But it also automatically includes header files needed  for your libraries,
making the entire process rather opaque. This would have been reason enough for
me to look into doing it differently, but really the elephant in the room that
needed changing was the poor, often belittled Arduino IDE. The IDE simply does
not do the toolchain justice.&lt;/p&gt;
&lt;h2 id=&quot;benefits-from-using-make&quot;&gt;Benefits from using Make&lt;a class=&quot;zola-anchor&quot; href=&quot;#benefits-from-using-make&quot; aria-label=&quot;Anchor link for: benefits-from-using-make&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Goals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use any editor and just run shell commands (or press buttons)&lt;/li&gt;
&lt;li&gt;Compile and flash the program immediately after checking out from version
control, not having to set up Arduino&lt;/li&gt;
&lt;li&gt;Do syntax highlighting and completion based on local files&lt;/li&gt;
&lt;li&gt;Symbol lookup (go to definition, find usage) and all the vim/IDE/ctags
goodness.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-easy-part-using-someone-else-s-makefile&quot;&gt;The Easy Part: Using Someone Else&#39;s Makefile&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-easy-part-using-someone-else-s-makefile&quot; aria-label=&quot;Anchor link for: the-easy-part-using-someone-else-s-makefile&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https://github.com/apmorton/teensy-template&quot;&gt;this repo&lt;/a&gt;, GitHub user
apmorton has prepared a working makefile. Only tiny adjustments are needed in
the provided makefile, like setting desired clock frequency, setting Teensy
version and enabling more compiler warning flags :)&lt;/p&gt;
&lt;h2 id=&quot;the-hard-part-getting-existing-code-to-compile-and-run&quot;&gt;The Hard Part: Getting Existing Code to Compile (... and run...)&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-hard-part-getting-existing-code-to-compile-and-run&quot; aria-label=&quot;Anchor link for: the-hard-part-getting-existing-code-to-compile-and-run&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I had used numerous Arduino libraries in my existing project. Here it became
apparent how much the Arduino IDE actually did in the backgound - after
including the libraries, there was a large wall of compiler warnings and
errors. Most of them can be fixed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If it is a missing (undeclared) function:
&lt;ul&gt;
&lt;li&gt;Looking up the header file it should be located in using google or man
pages&lt;/li&gt;
&lt;li&gt;Looking for that header file in ./teensy3 or ./tools using ripgrep or
similar&lt;/li&gt;
&lt;li&gt;Including that file, and seeing if that at least removes the error&lt;/li&gt;
&lt;li&gt;When all errors are fixed, taking a hard look at all the included code, and
whether it actually does the desired job&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If the issue are duplicate function definitions:
&lt;ul&gt;
&lt;li&gt;Difficult one. You need to find out which of the functions to use and then
comment out or guard (with a preprocessor definition) the others
definition.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Else:
&lt;ul&gt;
&lt;li&gt;Tough luck, you are on your own...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-hardest-part-fixing-remaining-issues-when-the-program-compiles-fine&quot;&gt;The Hardest Part: Fixing Remaining Issues When The Program Compiles Fine&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-hardest-part-fixing-remaining-issues-when-the-program-compiles-fine&quot; aria-label=&quot;Anchor link for: the-hardest-part-fixing-remaining-issues-when-the-program-compiles-fine&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It is likely that after compiling with only few errors, the program still has
different behaviour than when running under Arduino IDE... In my case, example
code from I2Cdevlib was not setting an interrupt pin&#39;s pinMode and thus the
interrupts were ignored when not using the IDE. Presumably, the IDE does some
special magic to fix this up, I don&#39;t know. Setting the pinMode fixed this.&lt;/p&gt;
&lt;p&gt;Good Luck!&lt;/p&gt;
&lt;p&gt;P.S. there is an even harder part - keeping the toolchain up to date. Using
platformio can fix this and get you all the benefits, but there is
something to be appreciated about just running &lt;code&gt;make flash&lt;/code&gt;...&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Remote Control vehicle balance controller</title>
        <published>2017-11-05T00:00:00+00:00</published>
        <updated>2017-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/remote-control-vehicle-balance-controller/"/>
        <id>https://barafael.github.io/posts/remote-control-vehicle-balance-controller/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/remote-control-vehicle-balance-controller/">&lt;p&gt;In this article, I want to present a PID-based multi-purpose balance controller
that runs on the Teensy 3.2 board using Arduino libraries. It can control
PWM-based actuators like servos or LEDs and electronic speed controllers
driving brushless motors. This control is based on an external signal like the
output from an RC receiver, and the output of an inertial measurement unit.&lt;/p&gt;
&lt;p&gt;That means you can use this controller to stabilise or balance small vehicles
like planes, multicopters, VTOLs, hydrofoils, hovercraft, or rockets...&lt;/p&gt;
&lt;p&gt;To get the most use out of this article, you should have a basic understanding
about PID, standard RC components like ESCs (electronic speed controllers),
brushless motors, RX/TX, and some C/C++ programming skills.&lt;/p&gt;
&lt;h2 id=&quot;why-use-pid-for-balance-control&quot;&gt;Why use PID for balance control?&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-use-pid-for-balance-control&quot; aria-label=&quot;Anchor link for: why-use-pid-for-balance-control&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A PID controller governs a system so that the difference between a setpoint and
a measured value is minimized, effectively driving our system to where we want
it to be. Note that anything measurable and &#39;steerable&#39; (that is at least
somewhat linear) can be fed into a PID controller, like temperature, position,
altitude, force... Using an IMU (Inertial Measurement Unit) to give us our
measurement, we can generate an output signal that depends on the attitude and
angular velocity of our system.&lt;/p&gt;
&lt;p&gt;In quadcopters, planes, and many other vehicle types, we have to constantly
monitor and manipulate the attitude, thrust, velocity and similar parameters to
achieve the desired result. To influence those parameters, there are control
surfaces, levers or propellers/jets which inflict forces on our craft in any
necessary degree of freedom.&lt;/p&gt;
&lt;p&gt;Those propellers and levers generally control rates too - rate of rotation,
rate of climb, etc. That makes them ideal for being governed by a PID
controller.&lt;/p&gt;
&lt;h3 id=&quot;cascaded-pid&quot;&gt;Cascaded PID&lt;a class=&quot;zola-anchor&quot; href=&quot;#cascaded-pid&quot; aria-label=&quot;Anchor link for: cascaded-pid&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;It is useful to use not only one but two PID controllers because the sensor
output from the gyroscope is way faster than the output from the sensor fusion
algorithm that fuses gyroscope and accelerometer data and produces an accurate
attitude estimation. Gyroscope data drifts only over time, whereas
accelerometer data does not drift but is subject to high-frequency noise. We
can cascade the controllers: the first loop receives the setpoint interpreted
as attitude and the currently most accurate estimation of the attitude and
produces a needed angular rate as a result. This rate is fed into another loop
as setpoint, and this rate loop receives the faster angular rate readings from
the gyroscope directly. If the second loop executes more often, then it will
ensure that the overall loop rate is fast and not limited by the time it takes
to fuse the IMU data.&lt;/p&gt;
&lt;p&gt;The setpoint can either be interpreted as a desired absolute angle or as a
desired angular rate. In the first case, the PID controller will attempt to
stabilize the craft to this angle, whereas in the second case, it will try to
rotate the vehicle at the given rate. This is known as &#39;rate mode&#39; or &#39;acro
mode&#39; in some flight controllers.&lt;/p&gt;
&lt;p&gt;To achieve &#39;rate mode&#39;, the attitude loop simply needs to be ignored. A
constant input on the roll stick of a plane in rate mode would result in a
continuous roll, or a multicopter yaw stick would control the rate of
z-rotation of the copter. In &#39;stabilize mode&#39;, a constant stick deviation is
mapped to a constant vehicle deviation.&lt;/p&gt;
&lt;h2 id=&quot;hardware&quot;&gt;Hardware&lt;a class=&quot;zola-anchor&quot; href=&quot;#hardware&quot; aria-label=&quot;Anchor link for: hardware&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I am using a Teensy 3.2 as the brains. It has an ARM Cortex M4 chip that can
be overclocked to 120MHz which is more than sufficient for this control task.
The board also has plenty of GPIO pins and can tolerate a wide range of supply
voltages (such as 5V from a standard RC electronic speed controller) with its
internal voltage regulator.&lt;/p&gt;
&lt;p&gt;As IMU sensor, I previously used the widely available and familiar MPU6050. This
sensor offers measurement of absolute orientation as well as angular rates from
the gyroscope and provides data moderately quickly using the I2C protocol.
But now I am using
&lt;a rel=&quot;external&quot; href=&quot;https://www.tindie.com/products/onehorse/ultimate-sensor-fusion-solution/&quot;&gt;Kris Winers EM-SENtral-based &#39;Ultimate Fusion Solution&#39;&lt;/a&gt;
which has proven to be extremely fast and accurate, if a bit expensive. The
sample rate for accelerometers and gyroscopes is set 1kHz for now. The
proprietary sensor fusion in the SENtral processor reacts extremely quick to
changes in angular position. I chose to let the sensors do their fusion for now
because it is initially very simple, but I would like to use one of the newer
Invensense sensors (ICM-20608, ICM-40602) and implement my own Kalman/Madgwick
filter at some point. The ICM-40602 improves on the previous generation mostly
in energy consumption, which is completely irrelevant in this case.&lt;/p&gt;
&lt;p&gt;As basic peripheral hardware (actuators), any standard ESCs, servos and TX/RX
combo using PWM should work.&lt;/p&gt;
&lt;h2 id=&quot;four-simple-steps&quot;&gt;Four simple steps&lt;a class=&quot;zola-anchor&quot; href=&quot;#four-simple-steps&quot; aria-label=&quot;Anchor link for: four-simple-steps&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here are the steps that need to be done to stabilize and control:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read input from the RC receiver&lt;/li&gt;
&lt;li&gt;Read sensor values from IMU&lt;/li&gt;
&lt;li&gt;Calculate PID response with those measurements as input&lt;/li&gt;
&lt;li&gt;Write the result to the connected actuators, using predefined weights&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;reading-input-from-the-receiver&quot;&gt;Reading input from the receiver&lt;a class=&quot;zola-anchor&quot; href=&quot;#reading-input-from-the-receiver&quot; aria-label=&quot;Anchor link for: reading-input-from-the-receiver&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The receiver sends pulses of varying on-time corresponding to the stick
positions to our board. Using interrupts, we can measure the time passing
between a rising edge and a falling edge of one signal, which should always be
roughly within 1000us and 2000us (RC standard). We can simply hook an interrupt
to each input pin, log the system time on a rising flank, and calculate the
duration in microseconds since rising flank when the signal is falling again.
The code for this is in &lt;code&gt;src/PWMReceiver.cpp&lt;/code&gt;. PPM, which is conceptually
similar but needs only one wire, is also implemented in
&lt;code&gt;src/PPMReceiver.cpp&lt;/code&gt;. All receiver interfaces should implement virtual
functions in &lt;code&gt;include/Receiver.h&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;race-copters-not-conditions&quot;&gt;Race Copters, Not Conditions&lt;a class=&quot;zola-anchor&quot; href=&quot;#race-copters-not-conditions&quot; aria-label=&quot;Anchor link for: race-copters-not-conditions&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The duration measurement from our interrupt routines is written each time the
interrupt routine executes on a falling edge. That means, we have to be
careful when reading those values! I used shared volatile variables which are
written to by the interrupts to store the measurements. The main loop copies
the data to variables which it can use undisturbed. This way, it is always
clear that the interrupt writes while the main loop reads the shared variables.
When the variables are read, no interrupts are allowed since they might
overwrite the values while reading them, violating the &#39;sharing XOR mutability&#39;
principle and thus inviting race conditions.&lt;/p&gt;
&lt;p&gt;For a really good description on how to read RC receiver PPM output, have look
at
&lt;a rel=&quot;external&quot; href=&quot;https://ryanboland.com/blog/reading-rc-receiver-values/&quot;&gt;this excellent article by Ryan Boland&lt;/a&gt;.
He explains it better than I will ever be able to - and with oscilloscope
screenshots!&lt;/p&gt;
&lt;h3 id=&quot;read-sensor-values-from-imu&quot;&gt;Read sensor values from IMU&lt;a class=&quot;zola-anchor&quot; href=&quot;#read-sensor-values-from-imu&quot; aria-label=&quot;Anchor link for: read-sensor-values-from-imu&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Reading the measurements and computation results from the &#39;Ultimate IMU
Solution&#39; is done in a similar way like in Kris Winers example program, however
I adapted large parts to skip software sensor fusion and provide an
object-oriented interface to the sensor.&lt;/p&gt;
&lt;h3 id=&quot;calculate-pid-response&quot;&gt;Calculate PID response&lt;a class=&quot;zola-anchor&quot; href=&quot;#calculate-pid-response&quot; aria-label=&quot;Anchor link for: calculate-pid-response&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is where the magic happens, but it is actually very simple. The PID
algorithm in this discrete form (really the one everyone uses) is short and
sweet, using the &quot;poor man&#39;s derivative (-)&quot; and the &quot;poor man&#39;s integral (+)&quot;.
Some smoothing is applied to the D term (if enabled), but I am unsure if this
is actually beneficial.&lt;/p&gt;
&lt;p&gt;I adapted some ideas presented in
&lt;a rel=&quot;external&quot; href=&quot;https://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/&quot;&gt;Brett Beauregard&#39;s series &quot;Improving the beginners PID&quot;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Eventually, PID coefficients will depend on the currently chosen mode (if I get
to the implementation).&lt;/p&gt;
&lt;h3 id=&quot;write-result-to-connected-actuators&quot;&gt;Write result to connected actuators&lt;a class=&quot;zola-anchor&quot; href=&quot;#write-result-to-connected-actuators&quot; aria-label=&quot;Anchor link for: write-result-to-connected-actuators&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The output is basically finished. It only needs to be scaled a bit and then
written out using the various output methods defined in
&lt;code&gt;src/ESCOutput.cpp&lt;/code&gt;, &lt;code&gt;src/ServoOutput.cpp&lt;/code&gt; and
&lt;code&gt;src/FastPWMOutput.cpp&lt;/code&gt;.  Eventually, this will need more work: depending
on the current flight mode, output mixer volumes will have to be chosen for
each output channel. Possible parameters for the output channel mixers are
throttle, roll/pitch/yaw attitude PID output, roll/pitch/yaw rate output,
rate/stabilize mode, and even motor type (servo/ESC).&lt;/p&gt;
&lt;p&gt;This is basically a Matrix-vector multiplication. Each output is the weighted
sum of the RC inputs and the PID controlling values in each axis. Since we have
8 outputs and 8+3 (currently) values that influence them, there are 8 rows and
11 columns in our matrix.  The input vector consists of 8 receiver inputs + 3
PID control values. The i-th row of the matrix consists of the weights for each
output for the j-th control value.&lt;/p&gt;
&lt;p&gt;This is a bit complex, but essentially it allows us to say: &quot;This output reacts
to the throttle stick with a factor of 0.8, and to the yaw pid value with a
factor of 0.1.&quot; Additionally, we can store a matrix for each flight mode, and
transition from one matrix to the next smoothly while transitioning flight
modes.&lt;/p&gt;
&lt;p&gt;Where is the catch? Well, none of this is implemented... The matrix
multiplication part can be done in
&lt;a rel=&quot;external&quot; href=&quot;https://forum.pjrc.com/threads/49479-Fixed-point-known-size-matrix-multiplication-on-teensy-3-2-3-5&quot;&gt;under a microsecond(!) on the teensy 3.5&lt;/a&gt;
using the capabilities of the Cortex M4. That is an interesting challenge and I
hope I will get to it.&lt;/p&gt;
&lt;p&gt;All of this depends on getting the PID and IMU and Output implementations to
work with 16 bit fixed-point numbers, and never floats.&lt;/p&gt;
&lt;h2 id=&quot;give-me-the-code&quot;&gt;Give me the Code!&lt;a class=&quot;zola-anchor&quot; href=&quot;#give-me-the-code&quot; aria-label=&quot;Anchor link for: give-me-the-code&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The code can be found at
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/barafael/raPID&quot;&gt;https://github.com/barafael/raPID&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;further-ideas-inspiration&quot;&gt;Further Ideas/Inspiration&lt;a class=&quot;zola-anchor&quot; href=&quot;#further-ideas-inspiration&quot; aria-label=&quot;Anchor link for: further-ideas-inspiration&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I am thinking about allowing for several different flight/operation modes which
consist mostly of a set of PID-coefficients and settings for mixers on each
actuator output. A mixer would control how much impact each PID output should
have on each actuator output.&lt;/p&gt;
&lt;p&gt;Transitioning between flight modes could interpolate the values of the two
mixers so that modes transition smoothly into each other.&lt;/p&gt;
&lt;p&gt;If this transitional flight mode interpolation sounds familiar to you, it might
be because of
&lt;a rel=&quot;external&quot; href=&quot;https://www.rcgroups.com/forums/showthread.php?1972686-OpenAeroVTOL-with-transitional-mixers-(perfect-for-VTOLs)&quot;&gt;OpenAeroVTOL&lt;/a&gt;.
It runs (really well) on the
&lt;a rel=&quot;external&quot; href=&quot;https://hobbyking.com/de_de/hobbyking-kk2-1-5-multi-rotor-lcd-flight-control-board-with-6050mpu-and-atmel-644pa.html?___store=de_de&quot;&gt;Hobbyking KK2.1.5 Multi-Rotor LCD Flight Control Board&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There is active and friendly support on the RCgroups forums, and it is often
stated that this board is able to stabilize almost anything small-scale.
However, development is confined by the hardware used (who knows for how long
HK will be making the kk-board), the development style (code drops on release
by the single author every couple months), and the word &#39;VTOL&#39; in the name. It
would be nice to really have a general controller not for just one niche,
sacrificing some features (Tailsitter option, Heli-style rotor control) for a
more general approach (also with more than the 3 flight modes which OAV has).
Additionally, OAV does not support a derivative gain (the D in PID), arguing
that this form of feedback is unnecessary for vehicles that naturally have a
high damping factor due to having a higher mass or large wings. The accuracy of
this statement is debatable, and to provide a more general approach a D gain is
nice to have (if only for meta-stable systems or niche cases like multicopters).&lt;/p&gt;
&lt;p&gt;Another feature of OAV is that it can entirely be configured via the onboard
LCD screen (that is a miracle, really). Since version 1.5, you may also use
(exclusively) Microsoft Excel to configure it, using a macro-based GUI in .xlsx
format (yes, really). I am not at the point to even think about this by a long
shot, but it would be nice to have a graphical configuration interface on a
computer that can set options on the board over a serial or even wireless
connection.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Nice error handling with Arduino blinking LED patterns</title>
        <published>2017-10-31T00:00:00+00:00</published>
        <updated>2017-10-31T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/nice-error-handling-with-arduino-blinking-led-patterns/"/>
        <id>https://barafael.github.io/posts/nice-error-handling-with-arduino-blinking-led-patterns/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/nice-error-handling-with-arduino-blinking-led-patterns/">&lt;p&gt;Errors (not human errors, but literally error conditions) can happen very
quickly even in simple Arduino projects.  For example, an external library
might sometimes fail to load data from memory due to unreliable hardware (like
with the MPU6050).  In this case, if you have a serial connection, you might
see the error description printed there. But what if you have no serial
connection because you are using your board without having a computer
connected?&lt;/p&gt;
&lt;p&gt;Using the LED and blinking in different patterns is not a great solution,
because you have to know or find out what the patterns mean, but it is often
the best solution available (and real hardware manufacturers often choose the
same method!).  In this blog post, I want to show a simple and somewhat elegant
way to do this.&lt;/p&gt;
&lt;p&gt;Here is the code: &lt;script
src=&quot;https://gist.github.com/barafael/d1a09af50de218b90638068cf394d7cb.js&quot;&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;Pretty self-explanatory! If you haven&#39;t worked with header files (like
&lt;code&gt;error_handling.h&lt;/code&gt;) before: they are really simple. Before your code gets
turned into binary for the Arduino, the content of the header file is placed at
it&#39;s corresponding &lt;code&gt;#include&lt;/code&gt;. Simple as that. This way, we can define our
error handling functions without cluttering our main program. The header file
must be in the same directory as the main sketch. You can rename the main
sketch, but if you rename the header file, you must also remember to change
it&#39;s &lt;code&gt;#include&lt;/code&gt; for the new header name.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exploring the precision of floating-point numbers</title>
        <published>2017-10-10T00:00:00+00:00</published>
        <updated>2017-10-10T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/exploring-the-precision-of-floating-point-numbers/"/>
        <id>https://barafael.github.io/posts/exploring-the-precision-of-floating-point-numbers/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/exploring-the-precision-of-floating-point-numbers/">&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https://fabiensanglard.net/floating_point_visually_explained/&quot;&gt;this
blogpost&lt;/a&gt;, Fabien
Sanglard explains how floating point numbers are generally displayed in modern
computers (using the &lt;code&gt;IEEE754&lt;/code&gt; Norm). His alternative perspective using
buckets and offsets is brilliant and explains a fact that may be
overlooked when using the standard explanation: the accuracy of floating point
numbers declines with a factor of 2 by each bucket!  That is because the same
&#39;amount&#39; of numbers is dispersed in any bucket, but the size of the bucket
doubles every time.&lt;/p&gt;
&lt;p&gt;I wanted to empirically show this and wrote this short C program:&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/barafael/49d58525be9ff7738d6a8dc281649642.js&quot;&gt;&lt;/script&gt;
&lt;h2 id=&quot;one-reason-unions-are-useful&quot;&gt;One reason Unions are useful&lt;a class=&quot;zola-anchor&quot; href=&quot;#one-reason-unions-are-useful&quot; aria-label=&quot;Anchor link for: one-reason-unions-are-useful&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This program uses a C union. Unions allow you to use the same memory for
multiple members, and every time you write one member, it also changes the
others. This may seem useless, but it is not. In this case, it allows you to
write to memory using the memory representation of &lt;code&gt;float&lt;/code&gt;, while reading the
same content of memory as individual bits. The union has 2 members, one
allowing to write and read a float, the other resembling the bit pattern of a
float as defined in the &lt;code&gt;IEEE754&lt;/code&gt; Norm. After writing to the float, you can
read and manipulate the exponent and mantissa from the embedded struct.&lt;/p&gt;
&lt;h2 id=&quot;printing-any-memory-content-as-binary-print-any-content-pointer-size&quot;&gt;Printing any memory content as binary [print_any(content pointer, size)]&lt;a class=&quot;zola-anchor&quot; href=&quot;#printing-any-memory-content-as-binary-print-any-content-pointer-size&quot; aria-label=&quot;Anchor link for: printing-any-memory-content-as-binary-print-any-content-pointer-size&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Casting the pointer to the memory content to a byte pointer (&lt;code&gt;uint8_t *&lt;/code&gt;)
allows us to index individual bytes. To access individual bits, we need to
generate a bit mask for each of them. We simply start at &lt;code&gt;0b1000 0000&lt;/code&gt; and
keep shifting left while using the index to access a single bit and print it.
Since the bit at position &lt;code&gt;n&lt;/code&gt; will still be interpreted as being of value &lt;code&gt;2^n&lt;/code&gt;
we need to check if it is set and print a &lt;code&gt;1&lt;/code&gt; if this is the case, hence the
ternary operator.&lt;/p&gt;
&lt;p&gt;We need this function to inspect a floating point number.&lt;/p&gt;
&lt;h2 id=&quot;floating-point-numbers-are-discrete-too-increase-float-content&quot;&gt;Floating point numbers are discrete, too... [increase_float(content)]&lt;a class=&quot;zola-anchor&quot; href=&quot;#floating-point-numbers-are-discrete-too-increase-float-content&quot; aria-label=&quot;Anchor link for: floating-point-numbers-are-discrete-too-increase-float-content&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We imagine floats as being very fine-grained. That is exactly what they are -
they do not allow for arbitrary accuracy, they are not what mathematicians
would call &lt;em&gt;dense&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;That means, we can take a float and increase it by exactly one tiny amount,
yielding the next-larger float in that bucket! That is what the function
&lt;code&gt;increase_float&lt;/code&gt; does.&lt;/p&gt;
&lt;p&gt;We construct a &lt;code&gt;float_parts&lt;/code&gt; union using the float as content. Then, we look
at the mantissa: if it is filled to the brim, we reset it to 0 and increase the
exponent by one. Otherwise, we simply increase the mantissa.&lt;/p&gt;
&lt;h2 id=&quot;putting-it-together-how-accuracy-declines-with-growing-exponent-print-accuracy-low-high&quot;&gt;Putting it together: How accuracy declines with growing exponent [print_accuracy(low, high)]&lt;a class=&quot;zola-anchor&quot; href=&quot;#putting-it-together-how-accuracy-declines-with-growing-exponent-print-accuracy-low-high&quot; aria-label=&quot;Anchor link for: putting-it-together-how-accuracy-declines-with-growing-exponent-print-accuracy-low-high&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here we keep increasing a float, and when the &#39;step size&#39; changes, we log it.
We also print the factor between the last and the current step size.&lt;/p&gt;
&lt;p&gt;This function runs way faster than I expected for some reason - it visits every
float there is between &lt;code&gt;low&lt;/code&gt; and &lt;code&gt;high&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There you have it! Empirical demonstration of how inaccurate floats (and
doubles, just later) really are.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>VIM has no keyboard shortcuts</title>
        <published>2017-10-08T00:00:00+00:00</published>
        <updated>2017-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/2017-10-8-vim-has-no-keyboard-shortcuts/"/>
        <id>https://barafael.github.io/posts/2017-10-8-vim-has-no-keyboard-shortcuts/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/2017-10-8-vim-has-no-keyboard-shortcuts/">&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https://stackoverflow.com/questions/1218390/what-is-your-most-productive-shortcut-with-vim&quot;&gt;this StackOverflow
post&lt;/a&gt;,
a question about the &#39;Most productive Vim keyboard shortcut&#39; sparks a long
discussion about Vim and productivity. In &lt;a rel=&quot;external&quot; href=&quot;https://stackoverflow.com/a/1220118&quot;&gt;this
answer&lt;/a&gt;, titled &lt;em&gt;&#39;Your problem with Vim is
that you don&#39;t grok vi.&#39;&lt;/em&gt; which is easily one of the most influential pieces of
Vim documentation and intro material on the internet, user Jim Dennis takes the
question apart and shows how Vim is not about shortcuts but about a language
for manipulating text. If you read and understood this answer, you probably
don&#39;t need to read this post here, since it is just my personal take on the
Vim philosophy.&lt;/p&gt;
&lt;h2 id=&quot;shortcuts-and-vim&quot;&gt;&#39;Shortcuts&#39; and Vim&lt;a class=&quot;zola-anchor&quot; href=&quot;#shortcuts-and-vim&quot; aria-label=&quot;Anchor link for: shortcuts-and-vim&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A shortcut in any other program is like a certain event that causes the program
to do a certain action. Like &lt;code&gt;F5&lt;/code&gt; in a browser or &lt;code&gt;CTRL+D&lt;/code&gt; in most
terminals.&lt;/p&gt;
&lt;p&gt;In Sublime Text, there is a shortcut to delete a line: &lt;code&gt;CTRL+UP+K&lt;/code&gt;. This
cannot be remembered easily, involves &lt;code&gt;CTRL&lt;/code&gt;, is generally hard to do and
impossible with just one hand (yes, I know there is also &lt;code&gt;CTRL+X&lt;/code&gt;). In Vim,
the same action happens on &lt;code&gt;dd&lt;/code&gt;. This seems arbitrary too, but actually it
fits well into the rest of the vim language, where &#39;d&#39; means to delete
something and a double tap means to apply an action on an entire line.
Moreover, this command can be combined with others as in a real programming
language and has the side effect of storing the line in some register. This is
not a shortcut, but an action from the language that makes up the way you
manipulate text in vim.&lt;/p&gt;
&lt;h2 id=&quot;actions-and-macros&quot;&gt;Actions and Macros&lt;a class=&quot;zola-anchor&quot; href=&quot;#actions-and-macros&quot; aria-label=&quot;Anchor link for: actions-and-macros&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The fact that actions in vim can be randomly made up on the fly indefinitely,
and combined with each other, is already very powerful. But there are even more
benefits: since a text edit is just a sequence of characters constituting the
action, the use of a macro is simply recording and playing back such a sequence
of characters. Because vim is awesome, it stores a macro in some register
(bearing the name you gave to the macro) so you can easily access, save for
later, or modify the actions a macro does. You can also call a macro from
itself for multi-line edits - to vim it is simply a long chain of characters
that it must interpret. Macros can be nested - you can call a macro b from
within macro a since macro invocation is only a sequence of characters.
Finally, it is easy to parameterize macros with register contents.&lt;/p&gt;
&lt;p&gt;For example, you might have a macro &#39;a&#39; that finds a word matching a certain
pattern and yanks it to register &#39;w&#39;, and then calls a macro &#39;b&#39; which finds
another word and substitutes the contents of the &#39;w&#39; register. This could be
done with regex back references, but to do it with macros in vim feels much
cleaner to me - it is like programming with functions.&lt;/p&gt;
&lt;h2 id=&quot;why-all-the-ramble-about-macros&quot;&gt;Why all the ramble about Macros?&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-all-the-ramble-about-macros&quot; aria-label=&quot;Anchor link for: why-all-the-ramble-about-macros&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Because all the other text editors which use shortcuts cannot really do this
and that is precisely the benefit of not having shortcuts, duh!&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Initial Commit</title>
        <published>2017-10-02T00:00:00+00:00</published>
        <updated>2017-10-02T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/2017-10-2-initial-commit/"/>
        <id>https://barafael.github.io/posts/2017-10-2-initial-commit/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/2017-10-2-initial-commit/">&lt;p&gt;This is a simple Jekyll-powered blog. I intend this blog to be a log of interesting things I come across while programming, studying math, or attempting to make hardware do things.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Negating the minimum representable number in twos complement</title>
        <published>2017-03-10T00:00:00+00:00</published>
        <updated>2017-03-10T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://barafael.github.io/posts/2017-10-3-negating-minimum-representable-number-in-twos-complement/"/>
        <id>https://barafael.github.io/posts/2017-10-3-negating-minimum-representable-number-in-twos-complement/</id>
        
        <content type="html" xml:base="https://barafael.github.io/posts/2017-10-3-negating-minimum-representable-number-in-twos-complement/">&lt;p&gt;Usually, we expect that negating a number yields a number which is of the same
absolute value, but with a flipped sign. However, there is a curious behaviour
in many programming languages where this property does not hold for one special
case. You might have come across this if you (like me) tried to (mis)use a
constant Integer.MIN_VALUE (or somesuch) to simulate something like negative
infinity. For example, this could be useful in a min-max algorithm with
alpha-beta pruning.&lt;/p&gt;
&lt;h2 id=&quot;what-s-the-issue&quot;&gt;What&#39;s the issue?!&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-s-the-issue&quot; aria-label=&quot;Anchor link for: what-s-the-issue&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you negate the lowest representable int in (for example) java, you could
expect it to become Integer.MAX_VALUE. This however, is literally far from the
truth! Instead, you get... Integer.MIN_VALUE again. How the flip did that
happen?&lt;/p&gt;
&lt;p&gt;In order to explain this behaviour, we have to dig a bit deeper into the way
signed integer numbers are represented in memory:&lt;/p&gt;
&lt;h3 id=&quot;two-s-complement&quot;&gt;Two&#39;s Complement&lt;a class=&quot;zola-anchor&quot; href=&quot;#two-s-complement&quot; aria-label=&quot;Anchor link for: two-s-complement&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you already know how Two&#39;s Complement works, just skip this. If not, here is
a short explanation:&lt;/p&gt;
&lt;p&gt;In order to represent both positive and negative numbers, we need to somehow
account for the sign of the number we are representing.  This can be done in
multiple ways, but Two&#39;s Complement has emerged as the most successful
approach. Basically, numbers are still just binary strings of bits, but the
Most Significant Bit (MSB) (the bit representing the largest power of 2) counts
negatively. For example, if we have the 8-bit binary number &lt;code&gt;0001 0011&lt;/code&gt;, 19
in decimal, everything is normal because the MSB is zero.  The number &lt;code&gt;1001 0011&lt;/code&gt; however would be interpreted as (-128) + 16 + 2 + 1, -109 in decimal.&lt;/p&gt;
&lt;p&gt;Determining the sign of a number becomes very simple: if the MSB is set, the
number is negative. Zero is represented as &lt;code&gt;0000 0000&lt;/code&gt;, negative one as
&lt;code&gt;1111 1111&lt;/code&gt; (the other 7 bits are needed to offset the large &#39;negative
weight&#39;), and the largest positive number is &lt;code&gt;0111 1111&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;negating-a-number-in-two-s-complement-and-ranges-of-representable-numbers&quot;&gt;Negating a Number in Two&#39;s Complement and Ranges of Representable Numbers&lt;a class=&quot;zola-anchor&quot; href=&quot;#negating-a-number-in-two-s-complement-and-ranges-of-representable-numbers&quot; aria-label=&quot;Anchor link for: negating-a-number-in-two-s-complement-and-ranges-of-representable-numbers&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The lowest representable number in Two&#39;s Complement is 2^(Place of MSB), while
the largest number is only 2^(Place of MSB) - 1. That is because the positive
numbers also need to include zero.&lt;/p&gt;
&lt;p&gt;Negating a number in Two&#39;s Complement is easy using this &#39;hand rule&#39;: start at
the right (Least Significant Bit LSB) and copy all zeroes and the first one.
Then, invert the rest.&lt;/p&gt;
&lt;h3 id=&quot;bringing-it-together&quot;&gt;Bringing it together&lt;a class=&quot;zola-anchor&quot; href=&quot;#bringing-it-together&quot; aria-label=&quot;Anchor link for: bringing-it-together&quot;&gt;🔗&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now we have everything that is needed to understand the behaviour shown above
where &lt;code&gt;-a = a&lt;/code&gt; (with &#39;a&#39; being some negative number).  There are actually
at least two ways to understand it, the first one involving the display range
and the other involving the &#39;hand rule&#39;.&lt;/p&gt;
&lt;p&gt;If you invert the lowest representable number with the hand rule, you don&#39;t
find a &#39;1&#39; until the very end. That means, you copy it and don&#39;t invert
anything! Or, using number ranges: the positive range is one less than the
negative range, which means that the lowest number simply cannot be inverted
without exactly one overflow! Which means, we end up at the place we started.&lt;/p&gt;
</content>
        
    </entry>
</feed>
