<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Max Desiatov]]></title><description><![CDATA[I'm Max Desiatov, a software developer]]></description><link>https://desiatov.com</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Feb 2023 18:30:35 GMT</lastBuildDate><item><title><![CDATA[Introduction to structured concurrency in Swift: continuations, tasks, and cancellation]]></title><description><![CDATA[This article is a part of my series about concurrency and asynchronous
programming in Swift. The articles are independent, but after reading…]]></description><link>https://desiatov.com/swift-structured-concurrency-introduction/</link><guid isPermaLink="false">https://desiatov.com/swift-structured-concurrency-introduction/</guid><pubDate>Thu, 14 Jan 2021 12:40:32 GMT</pubDate><content:encoded>&lt;p&gt;This article is a part of my series about concurrency and asynchronous
programming in Swift. The articles are independent, but after reading this one
you might want to check out the rest of the series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;&lt;a href=&quot;/closures#title&quot;&gt;How do closures and callbacks work? It’s turtles all the way
down&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;&lt;a href=&quot;/event-loops#title&quot;&gt;Event loops, building smooth UIs, and handling high server load&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Introduction to structured concurrency in Swift: continuations, tasks, and cancellation&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; This article is about an experimental feature, which is not available in a stable
version of Swift as of January 2021. APIs and behaviors described in this article may change without notice as new
development snapshots become available, but I will try to keep sample code updated as we get closer
to general availability of &lt;a href=&quot;https://github.com/DougGregor/swift-evolution/blob/structured-concurrency/proposals/nnnn-structured-concurrency.md&quot;&gt;structured concurrency&lt;/a&gt; in Swift.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;There are many discussions of the imminent introduction of &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; to Swift. The authors of
Swift concurrency proposals have done monumental work in preparing all of the related features. And
there are many of them. Just have a look at the actual “dependency tree” of the proposals:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/SwiftConcurrencyDependencies-dd58811a6b3b7d7f21b03f64b5dea026-a2a6f.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 25.91743119266055%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAmUlEQVQY03WPzQ6EIAyEef8H5KKcRTRIlB83wrpfaEz2sDsJyTDtdFp1/0JrLYQwTdO6rvD7DxTv3SFEnOd55pzxxxhfHa1DOmutQtR32r7vzrnjOCijpJS898uyQOZ51lrDt22DGGMIUJLD7PyglCJfPFK6rguRobEjdSAqyuM4DsOAyoXcybYyHhEPK7AITsLpIRxircX/AYEJH8JNCbEgAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The dependency tree of 10 separate concurrency proposals in Swift with async/await as the root&quot;
        title=&quot;&quot;
        src=&quot;/static/SwiftConcurrencyDependencies-dd58811a6b3b7d7f21b03f64b5dea026-fb8a0.png&quot;
        srcset=&quot;/static/SwiftConcurrencyDependencies-dd58811a6b3b7d7f21b03f64b5dea026-1a291.png 148w,
/static/SwiftConcurrencyDependencies-dd58811a6b3b7d7f21b03f64b5dea026-2bc4a.png 295w,
/static/SwiftConcurrencyDependencies-dd58811a6b3b7d7f21b03f64b5dea026-fb8a0.png 590w,
/static/SwiftConcurrencyDependencies-dd58811a6b3b7d7f21b03f64b5dea026-a2a6f.png 872w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;Around the time &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; proposal was accepted, I saw people asking almost the same set of
questions: how to convert legacy APIs to async? How an entrypoint to &lt;code&gt;async&lt;/code&gt; code would look like? While
examples of usage of &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; in UIKit apps were shared around, there were no good
examples that utilized the structured concurrency proposal. I wanted to have a look at some minimal
isolated code snippets that could help me answer these questions.&lt;/p&gt;
&lt;h2&gt;Setting up a SwiftPM project&lt;/h2&gt;
&lt;p&gt;Turns out, it’s relatively easy to set up a CLI project with SwiftPM that uses &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt;.
Please feel free to &lt;a href=&quot;https://github.com/MaxDesiatov/SwiftConcurrencyExample&quot;&gt;clone the final result from GitHub&lt;/a&gt;
to follow along. The &lt;code&gt;README.md&lt;/code&gt; file in the repository also contains important installation steps, as the
standard toolchain supplied in the latest stable Xcode currently won’t work. You’ll have to install
a development toolchain as described in the document to run this example code on your own machine.
In the rest of the article I’m going to review this example project piece by piece.&lt;/p&gt;
&lt;h3&gt;Compiler flags&lt;/h3&gt;
&lt;p&gt;Notice how the target needs to be declared in &lt;code&gt;Package.swift&lt;/code&gt;:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-property&quot;&gt;.target&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;ConcurrencyExample&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;dependencies&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;[],&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;swiftSettings&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;[&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.unsafeFlags&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;-Xfrontend&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;-enable-experimental-concurrency&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;]),&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;]&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Until Swift concurrency features become stable and enabled by default you have to pass these flags
when building. They are declared in the package manifest here so that you don’t have to pass them
each time manually when building the project.&lt;/p&gt;
&lt;h3&gt;Imports&lt;/h3&gt;
&lt;p&gt;When using &lt;a href=&quot;https://forums.swift.org/t/pitch-2-structured-concurrency/43452&quot;&gt;structured concurrency&lt;/a&gt;
to expose legacy callback-based APIs as &lt;code&gt;async&lt;/code&gt; functions, you currently have to import the
&lt;code&gt;_Concurrency&lt;/code&gt; module supplied with the latest Swift dev snapshots. The name of it starts with an
underscore to highlight that the module is experimental and its API may change.&lt;/p&gt;
&lt;h2&gt;Reviewing the code&lt;/h2&gt;
&lt;h3&gt;Continuations&lt;/h3&gt;
&lt;p&gt;While most of Apple’s APIs will be converted to &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt;
&lt;a href=&quot;https://github.com/apple/swift-evolution/blob/main/proposals/0297-concurrency-objc.md&quot;&gt;automatically&lt;/a&gt;,
your own callback-based code can be converted using a few helper functions, such as
&lt;code&gt;withUnsafeContinuation&lt;/code&gt; and &lt;code&gt;withUnsafeThrowingContinuation&lt;/code&gt;. They take a closure with a single
&lt;em&gt;continuation&lt;/em&gt; argument, and you’re supposed to call your callback-based code from this closure,
capture the continuation, and call &lt;code&gt;resume&lt;/code&gt; on it when you’re finished. Here’s how the declarations look for
the non-throwing variant for more context:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;UnsafeContinuation&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;resume&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;returning&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;withUnsafeContinuation&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;UnsafeContinuation&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;One of the most simple but practical enough example of a non-throwing async call is &lt;code&gt;sleep&lt;/code&gt;:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;import&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;_Concurrency&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;import&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Dispatch&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;seconds&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;await&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;withUnsafeContinuation&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;c&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.global&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;            &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.asyncAfter&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;deadline&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.now&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;+&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.seconds&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;seconds&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;))&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;                &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.resume&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;returning&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;())&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;            &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;And here’s a throwing variant:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;UnsafeThrowingContinuation&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;E&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;resume&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;returning&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;resume&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;throwing&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;E&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;withUnsafeThrowingContinuation&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;UnsafeThrowingContinuation&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Based on that we can convert &lt;code&gt;URLSession.dataTask&lt;/code&gt; to a throwing &lt;code&gt;async&lt;/code&gt; function:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;import&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Foundation&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;UnknownError&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Error&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Data&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;fetching \(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;)&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;await&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;withUnsafeThrowingContinuation&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;c&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;task&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;URLSession&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.shared.dataTask&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;error&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;            &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;switch&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;            &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;):&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;                &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.resume&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;throwing&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;            &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;):&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;                &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.resume&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;returning&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;            &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;):&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;                &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.resume&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;throwing&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;UnknownError&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;())&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;            &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.resume&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Here the continuation &lt;code&gt;c&lt;/code&gt; argument of the closure passed to &lt;code&gt;withUnsafeThrowingContinuation&lt;/code&gt; becomes
your “callback”. You have to call &lt;code&gt;resume&lt;/code&gt; on it exactly once with either a success value or an
&lt;code&gt;Error&lt;/code&gt; value. Multiple calls to &lt;code&gt;resume&lt;/code&gt; on the same continuation are invalid, since
&lt;code&gt;async&lt;/code&gt; functions can’t throw or return more than once. If you don’t ever call &lt;code&gt;resume&lt;/code&gt; on the
continuation you’ll get a function that never returns or throws, which is just as wrong as throwing
or returning more than once.&lt;/p&gt;
&lt;h3&gt;The entry point&lt;/h3&gt;
&lt;p&gt;As you probably noticed, in previous examples we got &lt;code&gt;async&lt;/code&gt; functions, but how do you actually call them from
non-&lt;code&gt;async&lt;/code&gt; code? Currently, the &lt;code&gt;runAsyncAndBlock&lt;/code&gt; function is an entry point you would use to
interact with an &lt;code&gt;async&lt;/code&gt; function from your blocking synchronous code:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-variable&quot;&gt;runAsyncAndBlock&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;task started&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;data&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;await&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;https://httpbin.org/uuid&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.utf8&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;end of main&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Note that in the current toolchain (&lt;code&gt;DEVELOPMENT-SNAPSHOT-2021-01-12-a&lt;/code&gt; at the moment of writing)
&lt;code&gt;runAsyncAndBlock&lt;/code&gt; does not take throwing closures as arguments, thus &lt;code&gt;try!&lt;/code&gt; or &lt;code&gt;do&lt;/code&gt;/&lt;code&gt;catch&lt;/code&gt; blocks
are required to call a throwing &lt;code&gt;async&lt;/code&gt; function such as &lt;code&gt;download&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;print&lt;/code&gt; statements here are added so that you can observe the execution sequence and to make sure
that your &lt;code&gt;async&lt;/code&gt; code is actually called.&lt;/p&gt;
&lt;p&gt;Remember that you should not use &lt;code&gt;runAsyncAndBlock&lt;/code&gt; in your GUI code running on the
main thread, as it will block the event loop from processing any input from your user. This will
result in your app being frozen until the &lt;code&gt;async&lt;/code&gt; closure body has finished. In a CLI app that
doesn’t expect any input this is fine though. In GUI apps you’d either have to call &lt;code&gt;runAsyncAndBlock&lt;/code&gt;
on a background thread that can be blocked, or use async handlers or actors to host your async code.
Given that proposals for async handlers and actors aren’t available yet, we’re leaving those
advanced topics out, and focus on a simple command-line app here.&lt;/p&gt;
&lt;h3&gt;Launching concurrent tasks with “async let”&lt;/h3&gt;
&lt;p&gt;Let’s say you need to fetch UUIDs for multiple entities, but you can only get a single one through
an asynchronous call. In some naive implementation you would &lt;code&gt;await&lt;/code&gt; for async calls repeatedly
one by one until you fetch all of the data. This is highly inefficient if these calls are independent
and can all run simultaneously without disrupting each other.&lt;/p&gt;
&lt;p&gt;You can launch multiple async tasks concurrently with &lt;code&gt;async let&lt;/code&gt; declarations. Then if you need to
wait for all of them to complete, just use a single &lt;code&gt;await&lt;/code&gt; marker on both of the values that
were declared with &lt;code&gt;async let&lt;/code&gt;:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;childTasks&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;\(&lt;/span&gt;&lt;span class=&quot;cm-builtin&quot;&gt;#function&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;) started&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;uuid1&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;https://httpbin.org/uuid&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;uuid2&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;https://httpbin.org/uuid&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;await&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;    ids fetched concurrently:&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;    uuid1: \(&lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;uuid1&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.utf8&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;    uuid2: \(&lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;uuid2&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.utf8&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Here two separate &lt;code&gt;uuid1&lt;/code&gt; and &lt;code&gt;uuid2&lt;/code&gt; tasks are launched concurrently, and they don’t block each
other. The &lt;code&gt;try await&lt;/code&gt; markers before &lt;code&gt;print&lt;/code&gt; mean that &lt;code&gt;print&lt;/code&gt; won’t evaluate before both of the
tasks have completed. Compare this with the old
&lt;a href=&quot;https://developer.apple.com/documentation/dispatch&quot;&gt;&lt;code&gt;Dispatch&lt;/code&gt;&lt;/a&gt; approach, where instead of &lt;code&gt;async let&lt;/code&gt; you’d have to set up a
&lt;a href=&quot;https://developer.apple.com/documentation/dispatch/dispatchgroup&quot;&gt;&lt;code&gt;DispatchGroup&lt;/code&gt;&lt;/a&gt; instance, which
is much more cumbersome to work with.&lt;/p&gt;
&lt;h3&gt;Cancellation&lt;/h3&gt;
&lt;p&gt;Tasks launched with &lt;code&gt;async let&lt;/code&gt; are called &lt;em&gt;“child tasks”&lt;/em&gt;, and this is important when you think
about cancellation. &lt;code&gt;async let&lt;/code&gt; forms an implicit task hierarchy which reflects call stacks of async
functions. In the code above &lt;code&gt;await childTasks()&lt;/code&gt; launches one parent task, which then spawns two
more child tasks for &lt;code&gt;download&lt;/code&gt; calls. When a parent task is cancelled, its child tasks are
cancelled too.&lt;/p&gt;
&lt;p&gt;The most critical thing to highlight is that cancellation with Swift’s structured concurrency is
cooperative, i.e. tasks need to “cooperate” in an explicit way to get cancelled as early as
possible. This is done with &lt;code&gt;checkCancellation()&lt;/code&gt; and
&lt;code&gt;isCancelled()&lt;/code&gt; static functions declared on the &lt;code&gt;Task&lt;/code&gt; type from the &lt;code&gt;_Concurrency&lt;/code&gt; module:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;extension&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Task&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Returns `true` if the task is cancelled, and should stop executing.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;///&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// This function returns instantly and will never suspend.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;static&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;isCancelled&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Bool&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// The default cancellation thrown when a task is cancelled.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;///&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// This error is also thrown automatically by `Task.checkCancellation()`,&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// if the current task has been cancelled.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;CancellationError&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Error&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// no extra information, cancellation is intended to be light-weight&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Check if the task is cancelled and throw&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// a `CancellationError` if it was.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;///&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// This function returns instantly and will never suspend.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;static&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;checkCancellation&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Why do you need to call these functions instead of the concurrency runtime just cancelling tasks
automatically? The runtime doesn’t know what your task is doing, it may need to save and close a
file handle, save the state of an expensive computation, or do whatever cleanup is needed.
Cancelling tasks preemptively would lead to much more complexity, while forcing tasks to account
for possible cancellation at any arbitrary line of code.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;try await Task.checkCancellation()&lt;/code&gt; call executed within a task will throw
&lt;code&gt;Task.CancellationError&lt;/code&gt; if this task was previously cancelled, meaning that everything that follows
it in the same function scope won’t be executed. If you actually have to do any meaningful cleanup,
add a &lt;code&gt;defer&lt;/code&gt; block or use a non-throwing &lt;code&gt;isCancelled()&lt;/code&gt; boolean check to manage this in even
more explicit way.&lt;/p&gt;
&lt;h3&gt;Task handles&lt;/h3&gt;
&lt;p&gt;How would you actually cancel a task? Remember we mentioned that &lt;code&gt;async let&lt;/code&gt; creates an implicit
hierarchy of child tasks. There’s a way to manage it explicitly with &lt;em&gt;detached tasks&lt;/em&gt; to which
you get a handle value as soon as you launch them. Such task has no implicit scope and is not
included in any task hierarchy, so you have to manage it yourself. How does the &lt;code&gt;Task.Handle&lt;/code&gt; type
look like that we’re operating on here?&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;extension&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Task&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Failure&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Equatable&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Hashable&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Retrieve the result produced the task, if is the normal return value, or&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// throws the error that completed the task with a thrown error.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Success&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;extension&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.Handle&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;where&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Failure&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;==&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Never&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Retrieve the result produced by a task that is known to never throw.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Success&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Importantly, task handles allow you to cancel a corresponding task:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;extension&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.Handle&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Cancel the task referenced by this handle.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;cancel&lt;/span&gt;&lt;span class=&quot;cm-punctuation&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 &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Determine whether the task was cancelled.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;isCancelled&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Bool&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;get&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;And to launch one and get a handle you should use &lt;code&gt;Task.runDetached&lt;/code&gt;:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;extension&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Task&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Create a new, detached task that produces a value of type `T`.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;@discardableResult&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;static&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;runDetached&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;priority&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Priority&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.default&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;@escaping&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Create a new, detached task that produces a value of type `T`&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// or throws an error.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;@discardableResult&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;static&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;runDetached&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;priority&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Priority&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.default&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;@escaping&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Note that you can even give a priority to such task, but I consider that a more advanced topic to
deserve its own separate article.&lt;/p&gt;
&lt;h3&gt;Cancellation is cooperative&lt;/h3&gt;
&lt;p&gt;Let’s see how it works in practice and add a cancellation check to &lt;code&gt;childTasks&lt;/code&gt;:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;childTasks&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;\(&lt;/span&gt;&lt;span class=&quot;cm-builtin&quot;&gt;#function&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;) started&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;uuid1&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;https://httpbin.org/uuid&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;async&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;uuid2&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;https://httpbin.org/uuid&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;await&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.checkCancellation&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;\(&lt;/span&gt;&lt;span class=&quot;cm-builtin&quot;&gt;#function&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;) is not cancelled yet&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;await&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;    ids fetched concurrently:&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;    uuid1: \(&lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;uuid1&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.utf8&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;    uuid2: \(&lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;uuid2&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.utf8&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;The function looks almost the same as previously with just two lines added in the middle:
&lt;code&gt;try await Task.checkCancellation()&lt;/code&gt; and a &lt;code&gt;print&lt;/code&gt; immediately after that.
To make things more interesting let’s launch a task that sleeps for one second, then starts
&lt;code&gt;childTasks()&lt;/code&gt;, and finally prints the result when that’s available:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-comment&quot;&gt;// run this as a detached task and get a handle for it&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;handle&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.runDetached&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;await&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;seconds&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;await&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;childTasks&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;())&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;To see the effect of cancellation, in our example the detached task is cancelled immediately after
it’s launched, errors from that are caught and printed:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-comment&quot;&gt;// cancel the task immediately through the handle&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.cancel&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;do&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;await&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.get&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;catch&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;if&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;error&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;is&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.CancellationError&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;task cancelled&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;else&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Let’s build and run the final example with cancellation and observe its output in the terminal:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;null&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span &gt;childTasks() started
fetching https://httpbin.org/uuid
fetching https://httpbin.org/uuid
task cancelled
end of main&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Hm, why does it print &lt;code&gt;childTasks() started&lt;/code&gt; if we cancelled the task immediately? Remember that
tasks that you launch have to explicitly check for cancellation and react appropriately. The &lt;code&gt;sleep&lt;/code&gt;
function does not check for anything, and the first cancellation check on the execution path happens
right after implicit &lt;code&gt;uuid1&lt;/code&gt; and &lt;code&gt;uuid2&lt;/code&gt; tasks are launched. But the result of these two downloads
is never printed, because the whole parent task doesn’t finish thanks to the cancellation check in
the middle.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this example we learned how to set up a SwiftPM CLI project with the new experimental concurrency
features enabled. We had a look at the new &lt;code&gt;_Concurrency&lt;/code&gt; module and new types introduced in it:
continuations and task handles. We learned how to call &lt;code&gt;async&lt;/code&gt; functions from non-&lt;code&gt;async&lt;/code&gt; code, how
to launch new concurrent tasks with &lt;code&gt;async let&lt;/code&gt; and detached tasks with &lt;code&gt;Task.runDetached&lt;/code&gt;. We also
had a look at cooperative cancellation and how to add support for it in your async code.&lt;/p&gt;
&lt;p&gt;Concurrency in Swift is a big topic, and there’s a lot more we omitted here that deserves its own
separate articles. I hope you liked this one, feel free to shoot a message on
&lt;a href=&quot;https://twitter.com/maxdesiatov&quot;&gt;Twitter&lt;/a&gt; or &lt;a href=&quot;https://mastodon.social/@maxd&quot;&gt;Mastodon&lt;/a&gt; with your
feedback!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The state of Swift for WebAssembly in 2020 (and earlier)]]></title><description><![CDATA[It probably all started with  an innocently-looking issue in the  emscripten 
repository  back in 2014: For context, back in 2014  the…]]></description><link>https://desiatov.com/swift-webassembly-2020/</link><guid isPermaLink="false">https://desiatov.com/swift-webassembly-2020/</guid><pubDate>Wed, 16 Sep 2020 12:40:32 GMT</pubDate><content:encoded>&lt;p&gt;It probably all started with &lt;a href=&quot;https://github.com/emscripten-core/emscripten/issues/2427&quot;&gt;an innocently-looking issue in the &lt;code&gt;emscripten&lt;/code&gt;
repository&lt;/a&gt; back in 2014:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/emscripten-1cc5974c26da770acca2d55922601864-3b8fd.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 70.1628664495114%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABYlAAAWJQFJUiTwAAACbUlEQVQ4y31Ty27UQBD0/x84cOOEhJA45ALiwgGJE0LikYdCgGS9uyHa2F6/14+Z8fhRVI/XIVywVOoZe1zdXdXj1U2LINfwY4Nt0mEba1StQd8P6GwP01nESYa8PEDOCrK8xKGqkRcl9woZY1XXaJWGF5UGZ3canzYaQWmhOiEaYEnYD6OD0gbadCTvXBKl57Ukm/fLdwtPCJKiRlo2KOuGWQukrEB+qty+RHmoUBDaWBSstGkVakK+HaoGmkStISmTeOM0sT2L3jIbyy7jGC1Jp35ut2GLLX+WinjUVSPvpfJWKTTEw8PvnuGBKIywJ0oS1VWFhKRRFKGiTtF+7xByH4Qhdvf3SNIU+32MXRCg4//vwi948vMEn9Nf8HJWdb72cXp9jcurHzg7v8DF5XfiCjerNdabLUkCRxQEIRPN5LL3NxsWUON9dIpnq7f4ml3Dqza/cff8BLev3sBf+Vj5a2RZ7pwU94ZheOhI5Jmk7/883rS6g3n6EvbFayhmU3SrbWfdlNZOJxkJ0VLMEaOmI/EwjhgJif04MOEIz440AxwTsssIWAENkTlcolQ2jtMxju6ckDx+liTezdUFvn38QPtbihyxzQppceAg1y7WrUbXjzCcTYmtjFMjrvc0J6M0BWX5S+5JZpFF2grC2UnBnk6H3N/TkGUdJ4kzRGA5ZpoOy42R+FDhInKe59hut0fcYrfbOYdvaNSabm74zqdhEkMmFClSmifES8uzKW4xuatWKevucaM6F3Uneo7uKj6GDLXrijOradw/Gi7MolFyMLyGvG7UU65jo4zTSh/xd21dAWlWwHAqHhP+AcjjLwxhVNQbAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A screenshot of a GitHub issue with title &quot;Unable to compile a simple Swift file (maybe not
possible?)&quot; and text &quot;Hi team, playing around with Emscripten in earnest for the first time, not my
usual area of work so apologies if this is clearly never going to work. What I&apos;d like to do is
compile a simple Swift program to JS&quot;&quot;
        title=&quot;&quot;
        src=&quot;/static/emscripten-1cc5974c26da770acca2d55922601864-fb8a0.png&quot;
        srcset=&quot;/static/emscripten-1cc5974c26da770acca2d55922601864-1a291.png 148w,
/static/emscripten-1cc5974c26da770acca2d55922601864-2bc4a.png 295w,
/static/emscripten-1cc5974c26da770acca2d55922601864-fb8a0.png 590w,
/static/emscripten-1cc5974c26da770acca2d55922601864-526de.png 885w,
/static/emscripten-1cc5974c26da770acca2d55922601864-fa2eb.png 1180w,
/static/emscripten-1cc5974c26da770acca2d55922601864-3b8fd.png 1535w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;For context, back in 2014 &lt;a href=&quot;https://en.wikipedia.org/wiki/Emscripten&quot;&gt;the Emscripten project&lt;/a&gt; was
built as a backend for &lt;a href=&quot;https://llvm.org&quot;&gt;LLVM&lt;/a&gt;-based compilers. While initially it produced
JavaScript and later its low-level subset &lt;a href=&quot;https://en.wikipedia.org/wiki/Asm.js&quot;&gt;asm.js&lt;/a&gt;, Emscripten
now mainly targets &lt;a href=&quot;https://en.wikipedia.org/wiki/WebAssembly&quot;&gt;WebAssembly&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As I wrote &lt;a href=&quot;/why-webassembly#title&quot;&gt;in my previous article&lt;/a&gt;, the availability of a virtual machine in all
relatively recent major browsers makes a lot of code much more portable. It easily follows that
Swift targeting WebAssembly would essentially make Swift available in some form on all platforms
that have browsers with WebAssembly support.&lt;/p&gt;
&lt;p&gt;I started thinking seriously about it in 2018, but I remember having some passing interest in
Emscripten and potential Swift support probably much earlier. By 2018 Swift was available on
Linux for two years already, people were actively trying to make it work well on Android, and
WebAssembly support in upstream LLVM became more or less stable, especially with &lt;a href=&quot;https://rustwasm.github.io/&quot;&gt;WebAssembly
support in the Rust compiler&lt;/a&gt; maturing to some point of usability.
In September I started playing with forks and patches that were shared in the original Emscripten
thread, and &lt;a href=&quot;https://github.com/emscripten-core/emscripten/issues/2427#issuecomment-423216845&quot;&gt;posted a quick
update&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/llvm7-progress-67c22b8c34a68e636f96a20f6b9a85e6-bc3d3.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 85.21739130434783%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAACi0lEQVQ4y4WU2W7bMBBF8919ab+n6Es/owiSIkm9RY4WS5ZkW/sukdTtDGW5doKgBi5mOBIP79AU7wLPxcvDPToxIsoqrbiokdcdsopEMa/7S140U140A5ph1Ko6gapXEHLE3c8f3/Ht6xekncLC9PFs7LC0fNiHHFaYae1OJcwg1XKjKffiGlkPRLWEfcxxKISG3wkpIZSCVEDVtKjqFnVLroqKVKIoK6RZgbKqSY0eV3Wja1leYMT0k2okDgHPY/T9gPXmFav1BptXQ8c1ablawdhu9bM306S4wauxJRk6OjsX4eEARabUSMBxnNYYBoHtm0mTLJiWBcfZYb/3Kbe1bMe5PLdsGzvX1XVe3PW8CaiugD0BDZpgbN/0i7z6HBnCdXZlUY3BLNueFvFo4UEIcogrh0LSyg61uNbtud4eJoE4sgNuzQ8CHRnqUT0IQjIyoOu6M/DKoSBgnKTIsgwJxThJaNNzRHGsxynV4zjROdc55kWBnHIeM+ZDy/OfMe2To51yjdvlGudzjbVYrvS2MJid3jicgTOA94ZzBnH+by9NnKJYO2cdTyekaYaSjtONQ0EHka1n2dRCWZYozy1xrlujttu6wmc/eQ3kT28RSjztBV58ic1RYhFIPHoCz77AE9WOxMo7IKGvg92AjrWeP07xHZA+Pb/H467Ds9djHfZYXo3/UM7PzdOAvFVnIDDP/wgcFJ68DvdOhweCMIDHv6yWxj1+uz1WwYBdIi4tjiOu8gtQDzFIwM0AKxp0DHMBNx/h5IBNtTCXl4nvNbd+41CKGqJy0JOBNvHp9qF6FKGzHAyapPQE9YmkUu+Akk58mxFwRNfQjUJXkaRbpaNbha46/fL/xOfwL3+rC8c/gvUXAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A screenshot of my comment for the same issue: &quot;LLVM 7.0 was released yesterday with a lot of
progress for WebAssembly target support. While the backend is still marked as experimental, not as
much patching of upstream LLVM repositories should be needed. I&apos;ve pulled 7.0 updates into Apple
swift&apos;s fork repositories and rebased the changes in the main swift repository by @patcheng, while
also fixing a few compilation issues.&quot;&quot;
        title=&quot;&quot;
        src=&quot;/static/llvm7-progress-67c22b8c34a68e636f96a20f6b9a85e6-fb8a0.png&quot;
        srcset=&quot;/static/llvm7-progress-67c22b8c34a68e636f96a20f6b9a85e6-1a291.png 148w,
/static/llvm7-progress-67c22b8c34a68e636f96a20f6b9a85e6-2bc4a.png 295w,
/static/llvm7-progress-67c22b8c34a68e636f96a20f6b9a85e6-fb8a0.png 590w,
/static/llvm7-progress-67c22b8c34a68e636f96a20f6b9a85e6-526de.png 885w,
/static/llvm7-progress-67c22b8c34a68e636f96a20f6b9a85e6-bc3d3.png 1150w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;The positive reaction surprised me to say the least, I knew the thread was long-running, but I
didn’t expect people to actually pay attention to it, and I still thought that WebAssembly was
perceived as a fringe technology at the time. &lt;/p&gt;
&lt;p&gt;Unfortunately, both LLVM and the Swift toolchain are not documented really well. Additionally, as I
learned from my own mistakes, to comfortably work with the codebase you have to be proficient not
just in C++ and compiler internals, but also in CMake, Python and Shell to be able to wrangle the
huge build system of the toolchain. Powerful hardware is also required, as clean builds can take
hours, and incremental builds are not very reliable. I didn’t know what I was doing, and even now
I’m just winging it. 🙈 I was just trying to resolve conflicts in patches from other people (mainly
&lt;a href=&quot;https://github.com/patcheng&quot;&gt;Patrick Cheng&lt;/a&gt;) and to make at least some code to build without
errors. &lt;a href=&quot;https://www.scribd.com/document/438739993/Compilers-principles-techniques-and-tools-Aho-Alfred-V-Sethi-Ravi-Ullman-Jeffrey-D-1942&quot;&gt;A book that I read many years
ago&lt;/a&gt;
and &lt;a href=&quot;https://modocache.io/&quot;&gt;blog posts by Brian Gesiak&lt;/a&gt; and &lt;a href=&quot;https://matt.diephouse.com/swift/&quot;&gt;Matt
Diephouse&lt;/a&gt; gave me some understanding of what things looked like,
and confidence that people outside Apple can do some work on it too.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/compilers-dragon-book-5e207a53e8b69862175e4811ffcb40b4-e5220.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGQAAAwADAAAAAAAAAAAAAAAAAAQFAgMG/8QAFgEBAQEAAAAAAAAAAAAAAAAAAQIA/9oADAMBAAIQAxAAAAGjlLdi2BcdIch7GOiGjH//xAAaEAADAQEBAQAAAAAAAAAAAAAAAQIDEhEi/9oACAEBAAEFAloqPsWqJM66SU+RqzPVdKejpktuvEf/xAAaEQACAgMAAAAAAAAAAAAAAAABAgAQESEi/9oACAEDAQE/AXRQdTiE5r//xAAXEQEAAwAAAAAAAAAAAAAAAAABABAh/9oACAECAQE/ARm3/8QAIBAAAQIFBQAAAAAAAAAAAAAAAAExAhAREmEiMlGBof/aAAgBAQAGPwLTEOpv8lFdwMnYwmWyVUcSsv/EABsQAQADAQEBAQAAAAAAAAAAAAEAESExQVFx/9oACAEBAAE/IcRBeWTTyDeSrtoYj9KyICzfFwsIpex9vSfqGrgLBb9JXhgjuvSOGT//2gAMAwEAAgADAAAAEHzLf//EABcRAQEBAQAAAAAAAAAAAAAAAAEAEWH/2gAIAQMBAT8QyCbO5FrYX//EABoRAAICAwAAAAAAAAAAAAAAAAABEBEhMWH/2gAIAQIBAT8Qc1krkSrUf//EABsQAQACAwEBAAAAAAAAAAAAAAERIQAxYUFR/9oACAEBAAE/EFSC4NNeTXcbix2JRuXWSFqd285WOADuHRiDM9VLG98z7TVuzg1uGoNFUfMgiI6iP1V12s2RPhDkEYaCMlAJEhHvMEAgBn//2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;The cover of &quot;Compilers: Principles, Techniques, and Tools&quot; by Alfred V. Aho, Ravi Sethi, and
Jeffrey D. Ullman published by Addison Wesley.&quot;
        title=&quot;&quot;
        src=&quot;/static/compilers-dragon-book-5e207a53e8b69862175e4811ffcb40b4-f8fb9.jpg&quot;
        srcset=&quot;/static/compilers-dragon-book-5e207a53e8b69862175e4811ffcb40b4-e8976.jpg 148w,
/static/compilers-dragon-book-5e207a53e8b69862175e4811ffcb40b4-63df2.jpg 295w,
/static/compilers-dragon-book-5e207a53e8b69862175e4811ffcb40b4-f8fb9.jpg 590w,
/static/compilers-dragon-book-5e207a53e8b69862175e4811ffcb40b4-e5220.jpg 768w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;small&gt;This book, a couple of blog posts from other people, my rusty (no pun intended!) knowledge of
C++, Python and Shell scripting, and my MacBook Pro 2018 (I still hate that keyboard) were probably
the only weapons I had when I started fighting the dragon.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;I was trying to keep up with upstream Swift and LLVM changes, working on it on and off, with some
things building, but nothing still worked end-to-end. By February 2019 I was blocked by Swift’s
reliance on &lt;a href=&quot;https://en.wikipedia.org/wiki/POSIX_Threads&quot;&gt;the pthreads API&lt;/a&gt; and
&lt;a href=&quot;https://en.wikipedia.org/wiki/Linearizability#Primitive_atomic_instructions&quot;&gt;atomics&lt;/a&gt;, none of
which were available in the initial version of WebAssembly (and still aren’t enabled in all browsers
by default). I was only able to work on it nights and weekends, while still doing software
consulting work during weekdays, which was my main source of income at the time. I still didn’t have
enough knowledge of the toolchain to make all necessary changes, and just resolving the conflicts
and waiting for multi-hour builds to complete consumed all the efforts I could spend on it.&lt;/p&gt;
&lt;p&gt;The most significant move forward happened when &lt;a href=&quot;https://twitter.com/zhuowei&quot;&gt;Zhuowei Zhang&lt;/a&gt; made it
all work with the freshly available &lt;a href=&quot;https://wasi.dev/&quot;&gt;WASI&lt;/a&gt; API and fixed most blocking runtime,
&lt;a href=&quot;https://belkadan.com/blog/2020/09/Swift-Runtime-Type-Metadata/&quot;&gt;metadata&lt;/a&gt; and linking issues. By
April-May 2019 &lt;a href=&quot;https://github.com/SwiftWasm&quot;&gt;the SwiftWasm organization&lt;/a&gt; was set up with first
toolchain builds uploaded and working with basic example code. He also deployed &lt;a href=&quot;https://swiftwasm.org/&quot;&gt;the SwiftWasm
website&lt;/a&gt; that hosts a simple demo, allowing you to download the compiled
WebAssembly binary.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/swiftwasm-announcement-b720e6d807c16be74db235821b0f420e-66900.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 22.445561139028474%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA0klEQVQY002PzY6EIBCEfRTFv+iBBeKIzigskAw7m+xNH8STj19rk8xmD5WPTprqqmyaJiyPO9ysYI3BPM/Q44i+71HXNVhZgjEGVhSJ5TVXVfXHpmnSXtu26LoO2XEcOM8Tr6+Ifd+xbVtSjBEheMyThrkO2U+PZTUYtcYwDOkwkcxIFEAIgcxaC+99WvAhwDmHdV3SOzxfiN8/MP6JuwmYFoebfqQkZEAks3dKSpwVV5U8zyGlBOccSqlEISSEuoGLAfxDXpXzVOv9kfTfjEj6Be0Bf7/pYpD1AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A tweet from @zhuowei: &quot;You can now compile Swift to WebAssembly to run on the Web.
Try it right now in your browser at https://swiftwasm.org!
Want to help? Join us @swiftwasm.&quot; retweeted by @clattner_llvm&quot;
        title=&quot;&quot;
        src=&quot;/static/swiftwasm-announcement-b720e6d807c16be74db235821b0f420e-fb8a0.png&quot;
        srcset=&quot;/static/swiftwasm-announcement-b720e6d807c16be74db235821b0f420e-1a291.png 148w,
/static/swiftwasm-announcement-b720e6d807c16be74db235821b0f420e-2bc4a.png 295w,
/static/swiftwasm-announcement-b720e6d807c16be74db235821b0f420e-fb8a0.png 590w,
/static/swiftwasm-announcement-b720e6d807c16be74db235821b0f420e-526de.png 885w,
/static/swiftwasm-announcement-b720e6d807c16be74db235821b0f420e-fa2eb.png 1180w,
/static/swiftwasm-announcement-b720e6d807c16be74db235821b0f420e-66900.png 1194w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;small&gt;The fact that &lt;a href=&quot;https://en.wikipedia.org/wiki/Chris_Lattner&quot;&gt;Chris Lattner&lt;/a&gt; himself is
interested in WebAssembly support is incredibly motivating!&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately, neither Zhuowei, nor I could put much time into making this work for something more
complex than a simple example. Specifically, on a lower level the Swift compiler makes a distinction
between &lt;a href=&quot;https://github.com/apple/swift/blob/release/5.3/docs/SIL.rst#function-types&quot;&gt;“thin” and “thick”
closures&lt;/a&gt;. Thin
closures are trivial, they don’t capture any surrounding vairables in its context (you can read more
details about closure environment &lt;a href=&quot;/closures#title&quot;&gt;in one of my previous articles&lt;/a&gt;). Also, Swift
error handling is implemented on a lower level as an additional pointer argument passed to throwing
functions, but thin closures can’t be throwing as they don’t take that argument. Thick closures
expect both context and error pointer arguments to be passed to them. These closure types might
seem to be incompatible, but on a high level Swift allows you to pass non-throwing closures where
throwing ones are expected:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-comment&quot;&gt;// Expects a non-throwing closure&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Void&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// Passes a non-throwing closure where a throwing one is expected.  &lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// Expects a throwing closure&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Void&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;This works on a lower level, because none of the existing hardware architectures care if you cast a
function with a specific number of arguments to a function with less arguments and ignore the rest
of them. You can compile the corresponding C code to x86 or ARM64 and it will work just fine:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;clike&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-variable&quot;&gt;#include&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;stdio&lt;/span&gt;&lt;span &gt;.&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;void&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;closure&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;int&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;argument&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;void&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;context&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;void&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;error&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;cm-variable&quot;&gt;printf&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;Argument is %d\n&quot;&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;argument&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;cm-variable&quot;&gt;int&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;main&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;void&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;cm-variable&quot;&gt;void&lt;/span&gt;&lt;span &gt; (&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;dropArguments&lt;/span&gt;&lt;span &gt;)(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;int&lt;/span&gt;&lt;span &gt;) &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&amp;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;closure&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;cm-variable&quot;&gt;dropArguments&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;42&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;/div&gt;
&lt;p&gt;Swift relies on the same trick where thin closures are cast as thick, and this was never a problem
that the Swift compiler previously encountered. WebAssembly is much stricter though when casting
function pointers. This C code will just crash when compiled to WebAssembly, and quite possibly you
won’t be able to launch it at all. Wasm hosts are required to run validation on supplied binaries
before execution. One of the validation checks includes verification that caller and callee function
signatures match exactly to each other in the number of arguments. &lt;/p&gt;
&lt;p&gt;This caused crashes in almost all non-trivial Swift code, as a lot of the standard library functions
(&lt;code&gt;map&lt;/code&gt; being the most widely used example) can take a throwing closure as an argument, but also
accept a non-throwing one. Fortunately, we’ve reached yet another significant milestone when &lt;a href=&quot;https://github.com/kateinoigakukun&quot;&gt;Yuta
Saito&lt;/a&gt; submitted &lt;a href=&quot;https://github.com/swiftwasm/swift/pull/6&quot;&gt;a
PR that worked around this problem&lt;/a&gt; in October 2019.
The whole issue of Swift relying on the function arguments mismatch trick still bites us
here and there, but at least we’re now aware of it, and all known instances of it are fixed in our
fork.&lt;/p&gt;
&lt;h2&gt;What’s going on with SwiftWasm in 2020?&lt;/h2&gt;
&lt;p&gt;By end of January 2020 &lt;a href=&quot;https://github.com/swiftwasm/swift/pull/34&quot;&gt;Yuta set up automated upstream
tracking&lt;/a&gt; with the wonderful &lt;a href=&quot;https://github.com/wei/pull/&quot;&gt;&lt;code&gt;pull&lt;/code&gt; GitHub
app&lt;/a&gt; that automatically submits PRs with changes from &lt;a href=&quot;https://github.com/apple/swift/&quot;&gt;Apple’s
repository&lt;/a&gt; to our fork. Thanks to this we no longer needed to do
it manually to keep up with upstream.&lt;/p&gt;
&lt;p&gt;In February-March I no longer had any full-time consulting engagements and decided that it was a
good opportunity to focus on open-source work full-time instead. The COVID thing has just started,
but it was also clear that it wouldn’t be easy to find consulting clients anyway in this economic
environment. In the meantime I wanted to polish some of the other open-source libraries I maintain,
and to focus on SwiftWasm as the next big thing in Swift for me personally. I’ve been doing it since
then, funding the efforts with my own savings and partially &lt;a href=&quot;https://github.com/sponsors/MaxDesiatov&quot;&gt;with the help from amazing GitHub
sponsors&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There’s a big dilemma here in my SwiftWasm development strategy. I can spend my time either on
submitting the changes from our SwiftWasm fork to the upstream Swift repository, or on developing
user libraries, improving documentation and writing example code. Kickstarting the ecosystem
allows people to build apps and lowers the barrier for contributions from the community, even
without WebAssembly becoming a platform officially supported in upstream distributions of Swift. &lt;/p&gt;
&lt;p&gt;Submitting PRs upstream on the other hand is very time consuming. Not only the changes need to be
polished to a high standard, but also, due to the reasons I’ve mentioned above, working on the
toolchain requires a ton of effort. On top of that, due to the limited amount of people available to
review PRs to the official Swift repository, sometimes you need to wait weeks for a review. Then if
any changes were requested, you apply the changes and wait for weeks again for a re-review. Obviously,
we can’t submit one giant PR for everything. So with about 150 files changed in our fork just in the
main &lt;code&gt;swift&lt;/code&gt; toolchain repository this will be multiplied by dozens if not a hundred PRs. There’s
also a comparable amount of changes to &lt;a href=&quot;https://github.com/swiftwasm/swift-corelibs-foundation/&quot;&gt;the Foundation
library&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At the same time, making all the changes available upstream would be a great boost to the overall
visibility of the project. But it doesn’t necessarily mean that the WebAssembly SDK will be
distributed with Xcode or with any other official Swift distribution. Most probably, Swift
developers targeting Wasm would need to download the toolchain and SDK separately just as they do
now. This download and installation process is already automated with &lt;a href=&quot;https://carton.dev&quot;&gt;a developer
tool&lt;/a&gt; we had to build for SwiftWasm anyway, so I don’t think that official
support would have a big impact on the actual developer experience. Given that I’m not employed by
any company funding this work, and that my savings and sponsorship revenue are limited, I decided
I’d rather spend the next months building libraries and writing documentation for our users rather
than drown in the upstreaming process, even though &lt;a href=&quot;https://github.com/swiftwasm/swift/issues/187&quot;&gt;some PRs have already been
submitted&lt;/a&gt; and a subset of those have been merged.
This doesn’t mean that upstreaming work will never be completed. It just won’t happen as soon as
some would expect, at least without more people joining the project and helping us out with this.&lt;/p&gt;
&lt;p&gt;In April I was sure that we were still pretty far from SwiftWasm becoming usable in complex
projects, but Yuta managed to make &lt;a href=&quot;https://github.com/swiftwasm/JavaScriptKit&quot;&gt;JavaScript bindings&lt;/a&gt;
work, which were demoed through the wonderful &lt;a href=&quot;https://github.com/kateinoigakukun/life-game-with-swiftwasm&quot;&gt;Game of Life
demo&lt;/a&gt; built with Swift and running in
the browser. This was the first example known to me of SwiftWasm interacting with browser DOM.
I consider this to be the most significant milestone this year. I also didn’t expect that SwiftPM
would work so well for this project, but it did, and with comparably minor changes.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/life-game-dev-b93bb679af2457ad41155c569e713b4c.gif&quot; alt=&quot;A short video of how the Game of Life built in Swift was developed, showing Xcode and hot reload
of the browser window when code changes are detected.&quot;&gt;&lt;/p&gt;
&lt;p&gt;Inspired by this, I decided to revive my old framework called &lt;a href=&quot;https://tokamak.dev&quot;&gt;Tokamak&lt;/a&gt;. It was
initially conceived in 2018 as a port of React to Swift and iOS, but that aspect of it obviously
became irrelevant after the release of SwiftUI. When SwiftUI was released, it really surprised me
how similar SwiftUI was to React after all, and it’s somewhat ironic, given how much aversion I saw
to React from an average Swift developer before SwiftUI have been introduced. SwiftUI, while built
with the same fundamental principles as React (and many other similar frameworks), is augmented with
language features that make it a lot more elegant with &lt;a href=&quot;https://docs.swift.org/swift-book/LanguageGuide/Properties.html#ID617&quot;&gt;property
wrappers&lt;/a&gt; and &lt;a href=&quot;https://swiftwithmajid.com/2019/12/18/the-power-of-viewbuilder-in-swiftui/&quot;&gt;function
builders&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I’m going to publish a detailed overview of Tokamak in the future, but for the purpose of
this article, I’ll just mention that in July of 2020 &lt;a href=&quot;https://github.com/TokamakUI/Tokamak/releases/tag/0.2.0&quot;&gt;the first release of Tokamak compatible with
WebAssembly and SwiftUI&lt;/a&gt; was tagged with
incredible amount of help from &lt;a href=&quot;https://github.com/carson-katri&quot;&gt;Carson Katri&lt;/a&gt;, &lt;a href=&quot;https://jedfox.com/&quot;&gt;Jed
Fox&lt;/a&gt;, &lt;a href=&quot;https://github.com/helje5&quot;&gt;Helge Heß&lt;/a&gt;, my sponsors, and many other
people who reported bugs and provided early feedback. There’s still enough of the SwiftUI API left
to implement, but I’m convinced that the general approach is viable, and more releases are coming
soon.&lt;/p&gt;
&lt;h2&gt;Future goals for SwiftWasm&lt;/h2&gt;
&lt;p&gt;Despite the fact that 2020 has been a horrible year so far from many perspectives, I’m deeply
grateful that I have an opportunity to work on a project such as this. We’re just getting started,
and there’s much more to do for the ecosystem to grow sustainably. I’ve prepared a list of some of
the issues that I’d like to see resolved sooner rather than later.&lt;/p&gt;
&lt;h3&gt;Short term&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Integrate &lt;a href=&quot;https://forums.swift.org/t/gsoc-lto-support-progress-report/37149&quot;&gt;binary size improvements developed by
Yuta&lt;/a&gt; into the 5.3 branch of
our SwiftWasm fork.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/TokamakUI/Tokamak/issues/216#issuecomment-664517970&quot;&gt;Enable SourceKit-LSP
support&lt;/a&gt; in our SwiftWasm
distributions.&lt;/li&gt;
&lt;li&gt;You currently can get access to the standard C library by using an &lt;code&gt;import Glibc&lt;/code&gt; statement in
your code. As the API of &lt;a href=&quot;https://github.com/webassembly/wasi-libc&quot;&gt;the WASI C library&lt;/a&gt; is
substantially different from the actual Glibc module, it should be exposed under a different name.
SwiftWasm users will have to use &lt;code&gt;import WASI&lt;/code&gt; instead of &lt;code&gt;import Glibc&lt;/code&gt; in later SwiftWasm
snapshots, but this will make the API differences explicit.&lt;/li&gt;
&lt;li&gt;Release SwiftWasm 5.3.0 after the official Swift 5.3.0 is available for other platforms.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Medium term&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Continue our upstreaming work to LLVM, Swift toolchain and SDK repositories.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set up &lt;a href=&quot;https://github.com/apple/swift-community-hosted-continuous-integration&quot;&gt;a community CI
node&lt;/a&gt; integrated with the
official CI Jenkins server.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;As Swift support for Windows hosts is going to be available in Swift 5.3, we need to make sure
that cross-compiling from Windows to WebAssembly works well. We also need to provide Windows
builds of the SwiftWasm toolchain and SDK. It’s not clear to me if Windows support for
5.3 also implies SwiftPM support, as right now it’s only included in builds off the &lt;code&gt;master&lt;/code&gt;
branch. If it doesn’t land in 5.3, SwiftWasm snapshots for Windows probably will only be available
off &lt;code&gt;master&lt;/code&gt; and in some future SwiftWasm version.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Similarly, we need to make sure that ARM64 builds of SwiftWasm are available for macOS Big Sur,
but as far as I know, none of SwiftWasm maintainers have access to the Apple Silicon DTK, and I
personally don’t have any budget for new Apple Silicon production hardware to be released later
this year. Sponsoring SwiftWasm maintainers so that we have access to hardware for testing would
be greatly appreciated. 🙏&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Research more opportunities for performance improvements and binary size reductions. We already
have a few in mind:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;JavaScript strings use UTF-16, while &lt;a href=&quot;https://swift.org/blog/utf8-string/&quot;&gt;Swift strings use UTF-8 encoding under the
hood&lt;/a&gt; since Swift 5. This means that every call into
JavaScript, especially for modifying DOM, incurs a re-encoding overhead. As Swift &lt;code&gt;String&lt;/code&gt;
API does not expose the underlying encoding directly, maybe we could go back to UTF-16 in
builds that target WebAssembly.&lt;/li&gt;
&lt;li&gt;One of the biggest dependencies in Swift binaries is &lt;a href=&quot;http://site.icu-project.org/home&quot;&gt;the ICU
library&lt;/a&gt;, which is used for locale-aware string conversions.
One way or another, the browser already has access to this code and exposes it to
JavaScript. I wonder if we could make Swift strings delegate this corresponding ICU-specific
code to the JavaScript API, meaning we’d no longer need to bundle ICU in every binary produced
by SwiftWasm.&lt;/li&gt;
&lt;li&gt;While WebAssembly is a “bare metal” platform with no basic facilities for memory allocation and
other basic APIs one would expect, WASI is a compatibility layer that gives you that. It is a
big dependency too, so we should explore if it could be stripped down just to memory allocators
and whatever other basic code is required to make things work. I’m sure it can be stripped down
substantially as &lt;a href=&quot;https://www.assemblyscript.org/runtime.html#variants&quot;&gt;the full AssemblyScript
runtime&lt;/a&gt; is only 2KB, while the WASI
JavaScript polyfill required for things to work in browsers, even without counting WASI itself,
is more than 200KB.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;WebAssembly and web APIs is a collection of different features and not all of them are always
implemented by all browsers. We should figure out a way to communicate it in our Swift code, and I
don’t think that making the Swift toolchain aware of every feature is a reasonable way forward.
That is, I’d prefer (versions are arbitrary) &lt;code&gt;@available(Chrome 242, Firefox 303, Safari 24)&lt;/code&gt;
attributes on functions to &lt;code&gt;@available(WebAssembly([.mvp, .multiThreading]))&lt;/code&gt;. The problem with
the latter approach is that the number of features will grow very fast, and one would want to
encode not only WebAssembly features, but DOM APIs too. For example, if your code uses &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API&quot;&gt;the Web
Animations API&lt;/a&gt; and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API&quot;&gt;the
Intersection Observer API&lt;/a&gt;,
would you want to specify both of those in the &lt;code&gt;@available&lt;/code&gt; attribute? Making the Swift compiler
aware of each feature is an unreasonable expectation, while the number of WebAssembly hosts is
limited and can be reasonably updated with time if new significantly popular hosts appear.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Speaking of web APIs, &lt;a href=&quot;https://github.com/swiftwasm/JavaScriptKit/&quot;&gt;JavaScriptKit&lt;/a&gt; gives us mostly
untyped API bindings, which is not ideal. There are some basic classes in JavaScript, such as
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date&quot;&gt;&lt;code&gt;Date&lt;/code&gt;&lt;/a&gt;,
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error&quot;&gt;&lt;code&gt;Error&lt;/code&gt;&lt;/a&gt;,
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise&quot;&gt;&lt;code&gt;Promise&lt;/code&gt;&lt;/a&gt;,
and a few more, but the browser DOM API is much more complex and is huge, and new features are
constantly added. It is untenable to create and maintain bindings for DOM manually with such a
small team as ours. Luckily, DOM APIs are usually available in &lt;a href=&quot;https://en.wikipedia.org/wiki/Interface_description_language&quot;&gt;the IDL
format&lt;/a&gt;, and &lt;a href=&quot;https://github.com/Apodini/webidl2swift&quot;&gt;a proof of
concept&lt;/a&gt; exists that can parse it and &lt;a href=&quot;https://github.com/j-f1/DOMKit&quot;&gt;generate bindings
automatically&lt;/a&gt;. We still need high-quality bindings for the basic
JavaScript classes to exist for it all to work well, so this is still in progress.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Long term&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;As I mentioned different WebAssembly features in the previous point, we should be aware of what’s
on the horizon to be able to support it. While multi-threading support would be great, &lt;a href=&quot;https://bytecodealliance.org/articles/reference-types-in-wasmtime&quot;&gt;the
WebAssembly reference types&lt;/a&gt;
proposal is even more exciting to me. Not only we would no longer need to maintain a lot of
interop code that bridges Swift and JavaScript, this could potentially allow Swift developers to
import WebAssembly modules with a simple &lt;code&gt;import&lt;/code&gt; statement and get most of the type information
exposed properly out of the box.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Integrating &lt;a href=&quot;https://github.com/tensorflow/swift&quot;&gt;Swift for TensorFlow&lt;/a&gt; with SwiftWasm would be a
nice expansion of limits of what’s possible with Swift, as running TensorFlow models in the
browser has a lot of practical use cases.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Come join us!&lt;/h2&gt;
&lt;p&gt;As you can see, there are many interesting and research-focused goals to accomplish. As the
ecosystem is in its early stage, it’s easy to make a substantial contribution to its foundations.
Please &lt;a href=&quot;https://github.com/swiftwasm/swift/issues&quot;&gt;review and file new issues&lt;/a&gt;, &lt;a href=&quot;https://github.com/swiftwasm/swift/pulls&quot;&gt;submit your
PRs&lt;/a&gt;, and &lt;a href=&quot;https://github.com/swiftwasm/swiftwasm-book&quot;&gt;improve the
documentation&lt;/a&gt;. Build your own projects and let me know
of your experience, either &lt;a href=&quot;https://twitter.com/MaxDesiatov&quot;&gt;on Twitter&lt;/a&gt; or &lt;a href=&quot;mailto:max@desiatov.com&quot;&gt;via
email&lt;/a&gt;!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How WebAssembly changes software distribution]]></title><description><![CDATA[If you had any experience with Windows and Internet Explorer in the 90s, 
quite probably you remember  ActiveX  controls. Most 
frequently…]]></description><link>https://desiatov.com/why-webassembly/</link><guid isPermaLink="false">https://desiatov.com/why-webassembly/</guid><pubDate>Wed, 09 Sep 2020 12:40:32 GMT</pubDate><content:encoded>&lt;p&gt;If you had any experience with Windows and Internet Explorer in the 90s,
quite probably you remember &lt;a href=&quot;https://en.wikipedia.org/wiki/ActiveX&quot;&gt;ActiveX&lt;/a&gt; controls. Most
frequently this involved bulky popups on pages with these controls having to display something
more complex than a few blocks of text.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/activex-0f260342e5426a0cc883966575235fe3.gif&quot; alt=&quot;Internet Explorer displaying an alert that requires ActiveX controls to be installed&quot;&gt;&lt;/p&gt;
&lt;p&gt;Or, remember &lt;a href=&quot;https://en.wikipedia.org/wiki/Java_applet&quot;&gt;Java applets&lt;/a&gt;? They became
available in 1995, and later they weren’t limited to just Windows and Internet Explorer. I remember
I had to use Java applets on macOS as recently as 2013, which chronologically is closer to the
present time than the 90s are. (Feeling so old anyway! 👴)&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/java-d07ca75d3ee42f845ec400952480dcd3-86a48.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.57692307692308%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIBBf/EABYBAQEBAAAAAAAAAAAAAAAAAAIAAf/aAAwDAQACEAMQAAAB6dUZNZf/xAAZEAACAwEAAAAAAAAAAAAAAAAAEgECESH/2gAIAQEAAQUCmvcMGGkY/8QAFREBAQAAAAAAAAAAAAAAAAAAEBH/2gAIAQMBAT8Bh//EABURAQEAAAAAAAAAAAAAAAAAAAAh/9oACAECAQE/AVf/xAAVEAEBAAAAAAAAAAAAAAAAAAAgMf/aAAgBAQAGPwKL/8QAGRAAAgMBAAAAAAAAAAAAAAAAAAEQEWHw/9oACAEBAAE/IeBizG0Fj//aAAwDAQACAAMAAAAQ8y//xAAWEQEBAQAAAAAAAAAAAAAAAAAAEQH/2gAIAQMBAT8QhMf/xAAWEQEBAQAAAAAAAAAAAAAAAAAAEQH/2gAIAQIBAT8Quqf/xAAcEAACAgIDAAAAAAAAAAAAAAAAAREhcZFBYYH/2gAIAQEAAT8QZOGadzIeuM+mKIarQurRh0f/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Microsoft&apos;s Application and Network Access Portal that displays a warning about user&apos;s browser not
allowing Java applets to run&quot;
        title=&quot;&quot;
        src=&quot;/static/java-d07ca75d3ee42f845ec400952480dcd3-f8fb9.jpg&quot;
        srcset=&quot;/static/java-d07ca75d3ee42f845ec400952480dcd3-e8976.jpg 148w,
/static/java-d07ca75d3ee42f845ec400952480dcd3-63df2.jpg 295w,
/static/java-d07ca75d3ee42f845ec400952480dcd3-f8fb9.jpg 590w,
/static/java-d07ca75d3ee42f845ec400952480dcd3-86a48.jpg 624w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Seems like ActiveX and Java applets were necessities mostly in the enterprise world, but
Macromedia Flash (later known as &lt;a href=&quot;https://en.wikipedia.org/wiki/Adobe_Flash&quot;&gt;Adobe Flash&lt;/a&gt;)
was certainly much more widely known to consumers. It was a requirement in the early days of streaming
video (even &lt;a href=&quot;https://www.theverge.com/2015/1/27/7926001/youtube-drops-flash-for-html5-video-default&quot;&gt;YouTube required
Flash&lt;/a&gt;
to work back then!), but also a major driver in browser gaming in late 2000s and early 2010s.
We certainly could blame Flash for making our browser windows look like this:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/flash-38961528058b4baa72341cf48381d93c-02110.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 63.20132013201321%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAP/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGoAP/EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEAAQUCX//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABYQAAMAAAAAAAAAAAAAAAAAAAAggf/aAAgBAQABPyEi/wD/2gAMAwEAAgADAAAAEDPP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGRAAAgMBAAAAAAAAAAAAAAAAAREQMUEA/9oACAEBAAE/ECVj4PUlk2aj/9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Browser page warning about Adobe Flash Player not being installed&quot;
        title=&quot;&quot;
        src=&quot;/static/flash-38961528058b4baa72341cf48381d93c-f8fb9.jpg&quot;
        srcset=&quot;/static/flash-38961528058b4baa72341cf48381d93c-e8976.jpg 148w,
/static/flash-38961528058b4baa72341cf48381d93c-63df2.jpg 295w,
/static/flash-38961528058b4baa72341cf48381d93c-f8fb9.jpg 590w,
/static/flash-38961528058b4baa72341cf48381d93c-02110.jpg 606w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;While ActiveX has seemingly failed to reach a significant adoption, Microsoft made yet another
attempt with &lt;a href=&quot;https://en.wikipedia.org/wiki/Microsoft_Silverlight&quot;&gt;Silverlight&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/silverlight-b8600e7fe201dbc24998a9aacecd3684-da6d6.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 56.79903730445246%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAgABBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe2hoZR//8QAGBABAQEBAQAAAAAAAAAAAAAAAAERAhL/2gAIAQEAAQUCkeYvLWq//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFhABAQEAAAAAAAAAAAAAAAAAADEg/9oACAEBAAY/AkTH/8QAGxAAAgIDAQAAAAAAAAAAAAAAAAERITFRYaH/2gAIAQEAAT8hQ1a8OAVOBIlsaz//2gAMAwEAAgADAAAAEKMP/8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQMBAT8QV//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABwQAAICAgMAAAAAAAAAAAAAAAABESFBoVHw8f/aAAgBAQABPxBI2jzSPhtcCWlejuQ6F4P/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Microsoft Silverlight page with an installation button&quot;
        title=&quot;&quot;
        src=&quot;/static/silverlight-b8600e7fe201dbc24998a9aacecd3684-f8fb9.jpg&quot;
        srcset=&quot;/static/silverlight-b8600e7fe201dbc24998a9aacecd3684-e8976.jpg 148w,
/static/silverlight-b8600e7fe201dbc24998a9aacecd3684-63df2.jpg 295w,
/static/silverlight-b8600e7fe201dbc24998a9aacecd3684-f8fb9.jpg 590w,
/static/silverlight-b8600e7fe201dbc24998a9aacecd3684-da6d6.jpg 831w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;In the meantime, Google was working on &lt;a href=&quot;https://en.wikipedia.org/wiki/Google_Native_Client&quot;&gt;its own thing for
Chrome&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/chrome_nacl-14dd7527a35d3d99235e94e99ca4ae06-5d9c9.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40.46153846153846%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsSAAALEgHS3X78AAABuElEQVQoz43R3UvTURjA8R9lF5b0p3QhClJXSVSC9Ia78MarbiIIIQgKiiiQEnq5yIYFpaalZZuGFDmQJmJz2iyLomj7DdJmsJff27bfy9nv29mKvKnwOXw4cJ7Dw3Oeo2x5EGB36AwHw+dpm7hA+7OLf+x9epaWx6dpGu2mWWr6rXmsm8ahkzTePs6uR6fovNzJuRNtbO9pRVHuH2XkbQQrWyCzvo5VLGIWLcqlEtHPy9xanOR6IsyNxIQU3vBGWgpxTe5980/oedFPQ+9+lK0Dx3j+bo7Mtx+k1DS6pmHoBoV8nrW1VXLZHJ7j4pZtydlg/+LIc0sziazE2NF7AKV+uINgJMLgeJzx6QSmqVPQdFxPUA3f9xEVIVX+QuAKr3Yv+iFO/ZV9KA0jAa6GJgkOzRJ8OENaTaKqKo7jsJnw5arGy6UoO/sCKNvuHWFqJc58LMnHrxmEzNsuWCVPztKTM/23at4oupiaz9TCHHumL6HU3T3MzJdFVlMpkqm0vCTn4vo1tlOhbIv/KtmyuF7tMEbX8h1ZsL+d2eQn8t9lZ3L4hqHVPiSXyyKE2PSTX71f4NDrm/wEhcQfOX7faHIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Google Native Client plug-in settings in the Chrome browser&quot;
        title=&quot;&quot;
        src=&quot;/static/chrome_nacl-14dd7527a35d3d99235e94e99ca4ae06-fb8a0.png&quot;
        srcset=&quot;/static/chrome_nacl-14dd7527a35d3d99235e94e99ca4ae06-1a291.png 148w,
/static/chrome_nacl-14dd7527a35d3d99235e94e99ca4ae06-2bc4a.png 295w,
/static/chrome_nacl-14dd7527a35d3d99235e94e99ca4ae06-fb8a0.png 590w,
/static/chrome_nacl-14dd7527a35d3d99235e94e99ca4ae06-5d9c9.png 650w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;It would be fair to say that these attempts failed to establish wide adoption, especially
after both consumers and businesses started shifting to mobile. Here’s how all these forays ended
according to Wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Microsoft dropped ActiveX support from the Windows Store edition of Internet Explorer 10 in
Windows 8. In 2015 Microsoft released Microsoft Edge, the replacement for Internet Explorer with
no support for ActiveX, this marked the end of the technology in Microsoft’s web browser
development.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://en.wikipedia.org/w/index.php?title=ActiveX&amp;#x26;oldid=969259090#Platform_support&quot;&gt;“ActiveX”&lt;/a&gt;
article on Wikipedia.&lt;/small&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Beginning in 2013, major web browsers began to phase out support for the underlying technology
applets used to run, with applets becoming completely unable to be run by 2015–2017. Java applets
were deprecated since Java 9 in 2017 and removed from Java SE 11 (18.9), released in September
2018.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://en.wikipedia.org/w/index.php?title=Java_applet&amp;#x26;oldid=972322018&quot;&gt;“Java applet”&lt;/a&gt;
article on Wikipedia.&lt;/small&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In July 2017, Adobe announced that it would declare Flash to be end-of-life at the end of 2020,
and will cease support, distribution, and security updates for Flash Player.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Adobe_Flash#End_of_life&quot;&gt;“Adobe Flash”&lt;/a&gt; article on
Wikipedia.&lt;/small&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There is no Silverlight plugin available for Microsoft Edge. It has not been supported by Google
Chrome since September 2015 or by Firefox since March 2017.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Microsoft_Silverlight#Demise&quot;&gt;“Microsoft Silverlight”&lt;/a&gt;
article on Wikipedia.&lt;/small&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;On October 12, 2016, a comment on the Chromium issue tracker indicated that Google’s Pepper and
Native Client teams had been destaffed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://en.wikipedia.org/w/index.php?title=Google_Native_Client&amp;#x26;oldid=973604804&quot;&gt;“Google Native
Client”&lt;/a&gt; article on
Wikipedia.&lt;/small&gt;&lt;/p&gt;
&lt;h2&gt;But JavaScript solved all these problems, didn’t it?&lt;/h2&gt;
&lt;p&gt;Most of these browser add-ons were introduced before modern JavaScript and HTML5 became available,
so one could argue you no longer need browser add-ons at all. Well, &lt;a href=&quot;https://daringfireball.net/linked/2017/06/27/web-without-javascript&quot;&gt;some
purists&lt;/a&gt; even say browsers
should have never supported JavaScript or any scripting whatsoever in the first place. Nevertheless,
there are enough use cases for browser scripting and browser apps in general that are hard to avoid.
When looking at the history of browser plugins in general, it’s hard not to notice a few themes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Distributing productivity apps via browsers is convenient in a lot of cases.&lt;/li&gt;
&lt;li&gt;Browser gaming made a lot of sense, especially for casual games.&lt;/li&gt;
&lt;li&gt;In both of these scenarios browsers had to display something more complex than text and a few
static images.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/flashelementtd-d00aec3e17cce46cb27a2b1662672bcf-d5c50.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 288px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 105.90277777777777%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAVABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAEDBP/EABcBAQEBAQAAAAAAAAAAAAAAAAABAgP/2gAMAwEAAhADEAAAAeQvLNQm4qg//8QAGxAAAQQDAAAAAAAAAAAAAAAAAAEQERMSMUH/2gAIAQEAAQUCkTRDcrMCs//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8BH//EABYRAAMAAAAAAAAAAAAAAAAAAAAQEf/aAAgBAgEBPwFw/8QAGBABAAMBAAAAAAAAAAAAAAAAAAEQQTH/2gAIAQEABj8CqGMRfX//xAAdEAADAQABBQAAAAAAAAAAAAAAAREhMVFhgbHh/9oACAEBAAE/IVlLEW8Rw5TSYJsdTyJSu8Op6CIq052JNfB//9oADAMBAAIAAwAAABBTwIL/xAAYEQADAQEAAAAAAAAAAAAAAAAAATERIf/aAAgBAwEBPxBvo6aU/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAEREP/aAAgBAgEBPxB5EQf/xAAdEAEBAAICAwEAAAAAAAAAAAABEQAhMUFR0fGB/9oACAEBAAE/EFCCRLOf3EjSS75M6QnaEyIOwUjm/NZADdmG+f6cABAS17zxIdyPvNBAAQPrP//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Flash Element TD game screenshot with a classic tower defense battle field&quot;
        title=&quot;&quot;
        src=&quot;/static/flashelementtd-d00aec3e17cce46cb27a2b1662672bcf-d5c50.jpg&quot;
        srcset=&quot;/static/flashelementtd-d00aec3e17cce46cb27a2b1662672bcf-399a3.jpg 148w,
/static/flashelementtd-d00aec3e17cce46cb27a2b1662672bcf-d5c50.jpg 288w&quot;
        sizes=&quot;(max-width: 288px) 100vw, 288px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;small&gt;The modern casual &lt;a href=&quot;https://en.wikipedia.org/wiki/Tower_defense&quot;&gt;tower defense game genre&lt;/a&gt;
arguably was reborn due to the popularity of Adobe Flash and browser gaming, with &lt;a href=&quot;https://en.wikipedia.org/wiki/Flash_Element_TD&quot;&gt;Flash Element
TD&lt;/a&gt; being a classic example.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Even though native apps were (and in many situations still are) objectively better for users, early
browser apps were attempting to build their own ad-hoc app stores before the App Store existed.
You didn’t have to buy a CD with an application and install it and manage it on your disk. You
didn’t have to install updates manually and migrate your data. There was no need to uninstall apps,
you just close a corresponding browser tab and forget about it.&lt;/p&gt;
&lt;p&gt;And when browser scripting capabilities became advanced enough, some people started seeing the
allure of making a browser version of their app the only version they provided. Browsers are
cross-platform, aren’t they? Just wrap your JavaScript app code in a browser-like container (say
&lt;a href=&quot;https://en.wikipedia.org/wiki/Electron_(software_framework)&quot;&gt;Electron&lt;/a&gt;) and distribute that instead
of your native app. &lt;/p&gt;
&lt;p&gt;But eventually not only the JavaScript APIs became more complex, the language itself could no longer
accommodate what developers wanted. Not everyone liked JavaScript syntax (remember
&lt;a href=&quot;https://en.wikipedia.org/wiki/CoffeeScript&quot;&gt;CoffeeScript&lt;/a&gt;?) or semantics (I couldn’t help but
notice that &lt;a href=&quot;https://en.wikipedia.org/wiki/TypeScript&quot;&gt;TypeScript&lt;/a&gt; has grown in popularity in recent
years). But it’s hard to transpile an arbitrary programming language to JavaScript, the latter was
not built with that goal in mind.&lt;/p&gt;
&lt;p&gt;Corollary, the JavaScript interpreter itself has both memory and performance overhead. Having a
garbage collector built in makes it even harder to transpile languages with different memory models
to JavaScript. The allure of having only one language to write all your apps for all platforms is
still there, but why do you have to be confined to JavaScript itself, even as a target language?&lt;/p&gt;
&lt;h2&gt;How WebAssembly actually started&lt;/h2&gt;
&lt;p&gt;With the death of browser plugins, at least we can praise the interoperability efforts of browser
vendors. Some lowest common denominator of JavaScript is supported in all browsers, and there is a
clear incentive for the vendors to keep up. With the demand to go beyond JavaScript, there were
initial attempts to support low level programming with asm.js in 2013:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Much of this performance gain over normal JavaScript [with asm.js was] due to 100% type consistency
and virtually no garbage collection (memory is manually managed in a large typed array).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Asm.js&quot;&gt;“asm.js”&lt;/a&gt; article on Wikipedia.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Syntactically this still looked pretty much like JavaScript, but when you have a lot of low level code,
the resulting file can get big pretty quickly, and the size of your code is pretty important when your
users download it frequently. As you weren’t supposed to write asm.js code manually most of the time,
and it was designed primarily as compilation target, it made sense to invent a binary format for it.
That’s basically how WebAssembly started:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;WebAssembly was first announced in 2015, and the first demonstration was executing Unity’s Angry
Bots in Firefox, Google Chrome, and Microsoft Edge. The precursor technologies were asm.js from
Mozilla and Google Native Client, and the initial implementation was based on the feature set of
asm.js.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/WebAssembly#History&quot;&gt;“WebAssembly”&lt;/a&gt; article on
Wikipedia.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/angrybots-af143aa014afd3462b9ef4d25875af9f-5b672.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 61.39462407479548%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAADX0lEQVQozx2TW0ybdRiHv8gxWxk1pVA22tIDPdAWaPm+nugpWymFtlBOG4eJDCZ0ymCjcxhNZINJZOoW4iaRbGyLWRxx0+hmdFETY7LEm7ldYIwXikYvTDTRqFe78PEbF7/kvXryvr/n/xekKhW6nQosZQqkKjWSUkFbnZ5j/V2kg24unB7k3HQ3CZuOsFbF0L5m9jr0LGTMnGy14iotQCorIqTexTOtLQjTrRLtThNGQSBQXsaoQ0lEXUp/1EeHDByK2cn3RAnWViM+uYusz83T7QE2lofptqkwlpRQu6OMtE7Fy30xhMUWA0ujbdQ+UcyIVcHvn47zxlwXCYsB0a7n/MUcP357kwcPPuby6/O4d1cTtJg4/9IYXl0lNVV2Gi0hAk0BrA4JYT2io9eiJ6xU0VlfxUfrp7h97RxLQ16WprKsrMxy95NVfvrlKzYf3uDqygnSDQ0kak1oikvRlu7AUFiMt1KDWalG2NyQN7g9wNeXDzEu2fDr9Gz9cJ9Hf9xl+bkODrVnGE/FWHvrCOvXF/j3tTzv5SaJSwHamlzkOkQuLBxkdXWO/GQ3wsWZYT4bEfn5i8N8tzFNt1x40u3g3jdfcnJulLG4n1wqKPcWY74rwmJIZNrnY9DZzKg/TD4R5e3lGW7cusSp2TGEXLSRvLmWd6zVzMQbSZmMuFVqbAYTNr2Wic4oPaKB47Z6XnWYGVBXMut08aIoMqE3MlVnZ1qUOBoNccwjypa9NdxZjLCWcOEv2YkoP506rRZBtv44u5XlTBpqmHfYiYtBIi4nSY+HzpYAYauFVHMD6YCP4b4MZ85MINx63stcVjalUpFvNOLUlG+DigsLKS4q2p6l6gqm+pP0RMNkwjE6JT/7jCYyMnxlJMT1qRDvzoTZur+E0O/U4VYoOZ0N8PlUJ9eSHoSCAgrlPIaVyKmv0hCrMzOeCJL2uGl1NJBpdLEmS9g8G+a3NzU82vTy9/c9CIMy8MqzCX69+QIPPzzL1uIRZvzWbZjLYuaV47PMHxwgKZ/XIm/1VChARO631+3kztEof13dy58f7OGf91X8d69JltIXpy8VIdEW4UA2zoFUkrRNT5H8A0J+H/t7e/C7m3DKgjSqClmWEW2FGod+D2FLNX2+Gg7vt3Ii62Y018X/U2jFkcjhK0cAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Angry Bots is a 3rd-person shooter demo that features a marine-like character that walks
through some futuristic research base and defends from suicidal four-legged robots&quot;
        title=&quot;&quot;
        src=&quot;/static/angrybots-af143aa014afd3462b9ef4d25875af9f-fb8a0.png&quot;
        srcset=&quot;/static/angrybots-af143aa014afd3462b9ef4d25875af9f-1a291.png 148w,
/static/angrybots-af143aa014afd3462b9ef4d25875af9f-2bc4a.png 295w,
/static/angrybots-af143aa014afd3462b9ef4d25875af9f-fb8a0.png 590w,
/static/angrybots-af143aa014afd3462b9ef4d25875af9f-526de.png 885w,
/static/angrybots-af143aa014afd3462b9ef4d25875af9f-fa2eb.png 1180w,
/static/angrybots-af143aa014afd3462b9ef4d25875af9f-08f6a.png 1770w,
/static/angrybots-af143aa014afd3462b9ef4d25875af9f-5b672.png 2567w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;small&gt;Angry Bots is still available to play on the &lt;a href=&quot;https://beta.unity3d.com/jonas/AngryBots/&quot;&gt;Unity
website&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;
&lt;h2&gt;What WebAssembly got right&lt;/h2&gt;
&lt;p&gt;Now you’re no longer restricted to JavaScript as a target language for browser apps. As soon as
&lt;a href=&quot;https://llvm.org/&quot;&gt;LLVM&lt;/a&gt; got WebAssembly backend more or less ready, it allowed compilers built
on top of LLVM (for C, C++, Rust, Swift and many more) to adopt it without rewriting everything from
scratch. This unlocked the browser environment to a huge amount of pre-existing software that can
also run close to native speed if optimized well.&lt;/p&gt;
&lt;p&gt;Not only can you run fun little projects such as &lt;a href=&quot;https://sandspiel.club/&quot;&gt;Sandspiel&lt;/a&gt; and
&lt;a href=&quot;https://orb.farm/&quot;&gt;orb.farm&lt;/a&gt; in your browser tab, but complex games such as &lt;a href=&quot;https://www.continuation-labs.com/projects/d3wasm/&quot;&gt;Doom
3&lt;/a&gt; (at least its demo version) are available too.
Both &lt;a href=&quot;https://blogs.unity3d.com/2018/08/15/webassembly-is-here/&quot;&gt;Unity&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/unrealengine/status/932624595722559490&quot;&gt;Unreal
Engine&lt;/a&gt; announced their support for
WebAssembly, and while we may not see AAA games running in browsers on their initial release date,
this still gives enough confidence in the maturity of the platform.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/orbfarm-d5127e6241542d4c77ee0faf5d5e8d41-9c30a.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 59.14209115281501%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAAC+ElEQVQozyWTW08bVxRG/QIBkjYQY+PLMDa+G98yvo3HHoxnPBePPXYAAzGOG6CIqg8taZo/UFXqc6X8gEpRo/Znrp7Cw5L2y1lnn7P3FziQ9sgkouRTEoX0PsX/yexTFjTLKbRahp6So18vMGjkMJp5jmopOuUDhu0yn//4k78+f+Hfv7/y9Z8vBLLJqBDFKeVkqoUkteIBjVKK7rGGZnh09D5t3UTrW/Ttcyz/HbOzG2aGyqRX4u7C44e5K7C4O58QKGViVHISrwsy9WKCVjFJ11RQfJeWfYLqnNF1z+hPr7CXv2LNv8eZ37J4e8m11+TiuMwbLY9Vkzk+jBJIRV6Sjm6Tje+Qi+2gFCUqrkptYNA6dmkcmTR1C3U0RV0uMNwJpuNhTE64HGks9CxzLcupmnokkAptkAlvkYs+Jy/qWv2A0qBDvevQtq5oDMfo5pie7dC/XDLyDZzRENN1mfkdrtpRFq0IKzXCbS8unhxepxp5hhLfQJWe0Ra3KUcdWi0dc37J7O4C03QZDo4xlid4c4e5M+DU05nP6vxuvuS3o01+Ubd4aG8RSO+skQ2uie7WqQj561aWstahUtfx3AGruXhy9wjTMjg9txjYJiPLwZucMnGb/Kx+y4/KBqvKJlflTQLx7XWkVxvIu5vI22uUKlmK2lBIPZo9B6VjU+kOGV/PeP9xhtI36Ngjupd3OGMb5/AVVjHIqBTEr4YIxILPie++QAp9gyTqYkaipo/JawYlcbCkCaFm0vA8VG9M1/CpWj7q4hzf7jGsxDDKkphw7JFASgqRkcPkEnvkkhEKyT30hoI7vqI2fUe1NxSCKY3BlKYtOnSWnK0WPNwO8XtlXPFFViONfiih5sTayNEgSSFNy0+JeVz01D6nww733zm8vfE5u35Px//A6I3Lp3uLjysdu50XaXlKjHqYEMi08mLK8fAO+5EgiViIAyn8xP4ecnwXTy/y6c7h4d7hw/WYn25c7k+aVLMy5bSEkhdhEDQKCYH8yH+4Oox9bVwTwgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;A pixel-art spherical fish tank filled with water, sand, algae, daphnia and fish.&quot;
        title=&quot;&quot;
        src=&quot;/static/orbfarm-d5127e6241542d4c77ee0faf5d5e8d41-fb8a0.png&quot;
        srcset=&quot;/static/orbfarm-d5127e6241542d4c77ee0faf5d5e8d41-1a291.png 148w,
/static/orbfarm-d5127e6241542d4c77ee0faf5d5e8d41-2bc4a.png 295w,
/static/orbfarm-d5127e6241542d4c77ee0faf5d5e8d41-fb8a0.png 590w,
/static/orbfarm-d5127e6241542d4c77ee0faf5d5e8d41-526de.png 885w,
/static/orbfarm-d5127e6241542d4c77ee0faf5d5e8d41-fa2eb.png 1180w,
/static/orbfarm-d5127e6241542d4c77ee0faf5d5e8d41-08f6a.png 1770w,
/static/orbfarm-d5127e6241542d4c77ee0faf5d5e8d41-9c30a.png 3730w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;small&gt;According to its creator, &lt;a href=&quot;https://orb.farm&quot;&gt;orb.farm&lt;/a&gt; is “a virtual ecosystem where different
species of creature can live, grow and die as part of a self-contained food chain”.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;It’s obviously not limited to games, as we can see Apple folks compiling their &lt;a href=&quot;https://twitter.com/lrz/status/1250453967957561344&quot;&gt;C++ and Objective-C
code from iWork&lt;/a&gt; to Wasm&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, or
&lt;a href=&quot;https://1password.com/&quot;&gt;1Password&lt;/a&gt; using it in their browser extension getting substantial
performance improvements as a result:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;With our move to WebAssembly, page filling and analysis now runs at least twice as fast as before,
and those websites with a large number of fields are up to 13x faster in Chrome and up to 39x
faster in Firefox! It’s blazing fast. 🔥&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://blog.1password.com/1password-x-may-2019-update/&quot;&gt;“1Password X: May 2019 update”&lt;/a&gt;
article on &lt;a href=&quot;https://blog.1password.com/&quot;&gt;the 1Password blog&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;
&lt;h2&gt;Wasm is a general purpose virtual machine&lt;/h2&gt;
&lt;p&gt;Not only you get performance improvements with WebAssembly compared to JavaScript, as it was
designed to run arbitrary code in your browser, it’s one of the most widely available secure sandbox
environments. And as a general purpose virtual machine, Wasm is not limited only to browsers.
&lt;a href=&quot;https://www.cloudflare.com/&quot;&gt;Cloudflare&lt;/a&gt; uses it for edge computing on their CDN:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We’re excited by the possibilities that WebAssembly opens up. Perhaps, by integrating with
Cloudflare Spectrum, we could allow existing C/C++ server code to handle arbitrary TCP and UDP
protocols on the edge, like a sort of massively-distributed inetd. Perhaps game servers could
reduce latency by running on Cloudflare, as close to the player as possible. Maybe, with the help
of some GPUs and OpenGL bindings, you could do 3D rendering and real-time streaming directly from
the edge.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://blog.cloudflare.com/webassembly-on-cloudflare-workers/&quot;&gt;“WebAssembly on Cloudflare
Workers”&lt;/a&gt; on &lt;a href=&quot;https://blog.cloudflare.com/&quot;&gt;the Cloudflare
blog&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;With people realizing the wide applicability of the Wasm tech stack, it was no surprise when
&lt;a href=&quot;https://wasi.dev/&quot;&gt;WASI&lt;/a&gt; (stands for WebAssembly System Interface) appeared. Where WebAssembly
itself is a “bare metal” platform, it does not supply any primitives such as memory allocation or
filesystem access, which WASI does provide. As Solomon Hykes, creator of Docker, &lt;a href=&quot;https://twitter.com/solomonstre/status/1111004913222324225&quot;&gt;puts
it&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If WASM+WASI existed in 2008, we wouldn’t have needed to created Docker. That’s how important it
is. Webassembly on the server is the future of computing. A standardized system interface was the
missing link. Let’s hope WASI is up to the task!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://twitter.com/solomonstre/&quot;&gt;@solomonstre&lt;/a&gt; on &lt;a href=&quot;https://twitter.com/solomonstre/status/1111004913222324225&quot;&gt;27 March
2019&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Many of you may know that shipping compilers or virtual machines &lt;a href=&quot;https://stackoverflow.com/questions/5054732/is-it-prohibited-using-of-jitjust-in-time-compiled-code-in-ios-app-for-appstor&quot;&gt;through the iOS App
Store&lt;/a&gt;
is prohibited. With Wasm you get the ultimate JIT compiler and virtual machine installed on any
relatively recent iOS device. Unsurprisingly enough, people have been able to ship &lt;a href=&quot;https://twitter.com/Textastic/status/1254664742960054277&quot;&gt;a C++ compiler
and a command line shell&lt;/a&gt; in an app
approved for App Store, so let’s hope this remains a legit way to distribute developer tools on iOS.
🤞&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ashell-59e3d6e03005d1c31bcccc66f65bc87b-26be2.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 74.96339677891655%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAC/9oADAMBAAIQAxAAAAGddfWo6wAr/8QAGhAAAgIDAAAAAAAAAAAAAAAAAgQAAwEiNP/aAAgBAQABBQJ3StcizfHjEq1+if/EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABURAQEAAAAAAAAAAAAAAAAAABAh/9oACAECAQE/Aaf/xAAdEAAABQUAAAAAAAAAAAAAAAAAAhAhQQEDERJx/9oACAEBAAY/Ai6s4I8oXFZFvqf/xAAZEAADAQEBAAAAAAAAAAAAAAAAARFhQXH/2gAIAQEAAT8hWyGfKwSbaCC0t5wWFp//2gAMAwEAAgADAAAAENAP/8QAFhEBAQEAAAAAAAAAAAAAAAAAAREQ/9oACAEDAQE/EILTP//EABYRAQEBAAAAAAAAAAAAAAAAAAEREP/aAAgBAgEBPxCgjn//xAAbEAEBAQACAwAAAAAAAAAAAAABEQAhUUGBsf/aAAgBAQABPxAw0ApFKzlyNPTo6NR0KSjy7zUE4fHR3v/Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;a-Shell and Textastic running side-by-side demoing a &quot;Hello, World!&quot; app written in C++ compiled
to WebAssembly and running on iOS&quot;
        title=&quot;&quot;
        src=&quot;/static/ashell-59e3d6e03005d1c31bcccc66f65bc87b-f8fb9.jpg&quot;
        srcset=&quot;/static/ashell-59e3d6e03005d1c31bcccc66f65bc87b-e8976.jpg 148w,
/static/ashell-59e3d6e03005d1c31bcccc66f65bc87b-63df2.jpg 295w,
/static/ashell-59e3d6e03005d1c31bcccc66f65bc87b-f8fb9.jpg 590w,
/static/ashell-59e3d6e03005d1c31bcccc66f65bc87b-85e3d.jpg 885w,
/static/ashell-59e3d6e03005d1c31bcccc66f65bc87b-d1924.jpg 1180w,
/static/ashell-59e3d6e03005d1c31bcccc66f65bc87b-9452e.jpg 1770w,
/static/ashell-59e3d6e03005d1c31bcccc66f65bc87b-26be2.jpg 2732w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://apps.apple.com/us/app/a-shell/id1473805438&quot;&gt;a-Shell&lt;/a&gt; and
&lt;a href=&quot;https://apps.apple.com/us/app/id1049254261?mt=8&quot;&gt;Textastic&lt;/a&gt; are available on the iOS App
Store.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;And what completely blew my mind recently is a JIT compiler for x86 binary code running in
browsers (not all browsers yet, it requires some features that are currently only supported in Chrome):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As part of CheerpX, we have implemented a fast x86 interpreter and JIT compiler that can generate
WebAssembly modules on the fly to efficiently execute arbitrary x86 applications and libraries,
fully client-side.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://medium.com/leaningtech/extreme-webassembly-1-pushing-browsers-to-their-absolute-limits-56a393435323&quot;&gt;“Extreme WebAssembly 1: pushing browsers to their absolute
limits”&lt;/a&gt;
on &lt;a href=&quot;https://medium.com/leaningtech&quot;&gt;Leaning Technologies’ Blog&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;
&lt;h2&gt;WebAssembly as a platform&lt;/h2&gt;
&lt;p&gt;As a secure and fast sandbox, Wasm also seems to be a good fit for application plugins. One could
imagine editors such as &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VSCode&lt;/a&gt; or &lt;a href=&quot;https://atom.io/&quot;&gt;Atom&lt;/a&gt; allowing
extensions to be written not only in JavaScript, but in any language that can target WebAssembly.
This would make their extensions ecosystem richer and unlock performance improvements that this
platform provides. Miguel de Icaza, the creator
of &lt;a href=&quot;https://www.mono-project.com/&quot;&gt;Mono&lt;/a&gt; and &lt;a href=&quot;https://dotnet.microsoft.com/apps/xamarin&quot;&gt;Xamarin&lt;/a&gt;
agrees, and goes further with this idea:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[…] IDEs/Editors/Tools could leverage WebAssembly to host their favorite language for scripting
during the development stage, but for the final build of a product (like Unity, Godot, Rhino3D,
Unreal Engine and really any other application that offers scripting capabilities) they could
bundle the native code without having to take a WebAssembly dependency.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://tirania.org/blog/archive/2020/Mar-02.html&quot;&gt;“Scripting Applications with
WebAssembly”&lt;/a&gt; on &lt;a href=&quot;https://tirania.org/blog/&quot;&gt;Miguel de Icaza’s
Blog&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;WebAssembly is arguably a more direct path towards achieving the idealistic goal of “write once, run
anywhere” than Java/JVM ever was. This is thanks to the open nature of the whole stack, potential
developer mind share (spanning big and diverse set of languages and ecosystems), and direct
involvement of browser vendors such as Apple, Google, Mozilla and Microsoft. This is the opposite to
the fractured ecosystem we saw in the 90s and 00s, where every vendor had their own
special plugin and forced you to use a specific programming language as a gatekeeping measure.&lt;/p&gt;
&lt;h2&gt;What WebAssembly still needs&lt;/h2&gt;
&lt;p&gt;As with any tech stack in its early years, not everything is hunky-dory in the WebAssembly land. It
would be unfair if I didn’t mention that &lt;a href=&quot;https://thenewstack.io/the-pain-of-debugging-webassembly/&quot;&gt;debugging with &lt;code&gt;print&lt;/code&gt;
statements&lt;/a&gt; is still a thing when
targeting Wasm, or that &lt;a href=&quot;https://github.com/WebAssembly/threads/&quot;&gt;multi-threading support&lt;/a&gt; is not
available in all browsers and formally haven’t reached the implementation stage yet. The lack of
&lt;a href=&quot;https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md&quot;&gt;stable ABI for dynamic
linking&lt;/a&gt; is not
critical and static linking makes some things somewhat easier, but it can still bite at times.&lt;/p&gt;
&lt;p&gt;The fact that the vast majority of consumer computing devices (92% as of September 2020 according to
&lt;a href=&quot;https://caniuse.com/#search=webassembly&quot;&gt;caniuse.com&lt;/a&gt;) have a universal virtual machine that can be
targeted by virtually any programming language is still fascinating to me. What WebAssembly
definitely needs is more attention from developers, and if all goes well, in a few years we’ll see
even more products that weren’t possible before.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Wasm is an abbreviation, but not an acronym, and it is the capitalization that &lt;a href=&quot;https://webassembly.org/&quot;&gt;WebAssembly spec authors use&lt;/a&gt; (in addition to the all-lowercase “wasm”). Thus, we should follow the authors with this capitalization variant, unless you’re one of those, who writes “IOS”, “XCode” or “IPhone”. 🙈&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Unbreakable reference cycles in Swift no one is talking about]]></title><description><![CDATA[When using Swift, one of the most important things to consider is a difference
between value types and reference types. We know that a…]]></description><link>https://desiatov.com/swift-reference-cycles/</link><guid isPermaLink="false">https://desiatov.com/swift-reference-cycles/</guid><pubDate>Mon, 17 Dec 2018 12:40:32 GMT</pubDate><content:encoded>&lt;p&gt;When using Swift, one of the most important things to consider is a difference
between value types and reference types. We know that a static type system is
useful to avoid type errors, similarly a guarantee that constant values stay
immutable is quite handy to avoid errors in stateful code. Unfortunately, for
certain reasons immutability and reference types in Swift are mutually exclusive
by default. Also, value types and reference types involve different approaches
to memory management: value types are implicitly copied while reference types
only change their reference count when passed around. Without proper care, it’s
easy to create reference cycles with reference types which cause &lt;strong&gt;memory
leaks&lt;/strong&gt;. Would it make sense to avoid classes altogether to avoid that and
get immutability when needed as a nice bonus?&lt;/p&gt;
&lt;p&gt;Not so fast, there might be more problems than one could anticipate. What
follows is a result of my trial and error when using Swift and the last few
sections describe nuances that I haven’t seen described anywhere, but in my
opinion are quite easy to stumble upon.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/memory_leaks-ea460f891f590a9e4f30bc5f24135fed-772df.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 400px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAABzklEQVQ4y52TyUotMRCG09oenEFxIYID5Igo3I2KHmdFxGHhjK5ErhM4oAsV7u66c+PGrW/Qx6fwCXyF9Jv4VZLuk3YlNnykkkr/VUmqlOIrJ6kqV1Nl7aq1o2zu1yKdmMjtNeKrcxjvNyrYbIpiiQmF6vHHwd5IffsKYplIlkWwNsTGYV1Nx7EnYQS6a750DmahJ9PgBLlWLqarphGhCvNFzzbMwyFcwCD+HsYT+AfNYeZaBOX+vGgrjjWOvIQ95sVm8S8wrsMy/j3GAQLL/A5Gg3uvHdunOwXy84Zni/UNAuxgr/osL7UL9Ad6CTajk7SMHecZ+pT7WfwLksExHLD5GO7x7TLf9IJXBPnvAhiZV1zmaUf4HvKyJSbX8AyncA77cMaPMn+EI+w3xicCNZFNizyKXAlZltxJ09qFMnYR/ZZND3DjxOw9vcA7fPDDp7xwcFVSjyPBteWOvGS0LWozbY+Y2MfpBAn0Cius1eu8oNMGXwVxXpNBtUs3qJ98WSbaXpXpK2QYPrktUNc5kW8xj7WVbbdCm5pmqVdfw8XS+Ra50N/a22FXQTsiJYHgsfrNFwjG0iVk6LopkdFMELjt16K+3KRV20Vcu+PHX2w6d7w6mCwuAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Memory leaks!&quot;
        title=&quot;&quot;
        src=&quot;/static/memory_leaks-ea460f891f590a9e4f30bc5f24135fed-772df.png&quot;
        srcset=&quot;/static/memory_leaks-ea460f891f590a9e4f30bc5f24135fed-871f0.png 148w,
/static/memory_leaks-ea460f891f590a9e4f30bc5f24135fed-84726.png 295w,
/static/memory_leaks-ea460f891f590a9e4f30bc5f24135fed-772df.png 400w&quot;
        sizes=&quot;(max-width: 400px) 100vw, 400px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;center&gt;&lt;i&gt;Reference cycle = memory leak!&lt;/i&gt;&lt;/center&gt;&lt;br/&gt;
&lt;h2&gt;Wait, remind me how memory management works in Swift&lt;/h2&gt;
&lt;p&gt;If you have good knowledge of how to use &lt;code&gt;weak&lt;/code&gt; keyword and how memory
management works for value and reference types, feel free to skip to &lt;a href=&quot;#advanced&quot;&gt;the
section with more advanced examples&lt;/a&gt;. Otherwise, consider this super
simple code:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;S&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;S init&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;f1&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;S&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// one allocation for S()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;S init&quot; is printed here&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;original&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// copy of `original` that can be optimised by the compiler&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;copy&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;original&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;copy&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// both `original` and `copy` out of scope here&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// copy of `original` that can be optimised by the compiler&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f1&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// value stored in `s` is dellocated here&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;result&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;nil&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Here memory management is trivial:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A value of type &lt;code&gt;S&lt;/code&gt; is allocated and assigned to &lt;code&gt;original&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Storage of &lt;code&gt;original&lt;/code&gt; is copied to &lt;code&gt;copy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;On return from function &lt;code&gt;f1&lt;/code&gt; value &lt;code&gt;original&lt;/code&gt; goes out of scope and is
deallocated.&lt;/li&gt;
&lt;li&gt;The return value from &lt;code&gt;f1&lt;/code&gt; is copied to &lt;code&gt;result&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;copy&lt;/code&gt; itself is deallocated as out of scope.&lt;/li&gt;
&lt;li&gt;When &lt;code&gt;nil&lt;/code&gt; is assigned to &lt;code&gt;result&lt;/code&gt;, that &lt;code&gt;result&lt;/code&gt; is deallocated.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All of these copies can be optimised away by the compiler and in the generated
optimised code you’d only see one allocation, zero copies and one final
deallocation. This means only steps 1 and 6 would execute (with &lt;code&gt;result&lt;/code&gt; and
&lt;code&gt;original&lt;/code&gt; aliasing the same value), but from programmer’s perspective, the
behaviour would stay the same.&lt;/p&gt;
&lt;p&gt;Why the same? Note that &lt;code&gt;&quot;S init&quot;&lt;/code&gt; is printed only once. There’s no notion of
“copy initialiser” in Swift, creating a copy of a value only copies its storage
without calling &lt;code&gt;init&lt;/code&gt;. This means we don’t expect any code to be executed
on these copies and some of them can be optimised away by the compiler without
changing the behaviour of resulting executable code.&lt;/p&gt;
&lt;p&gt;Now compare this to memory management with classes:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;C&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;C init&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;deinit&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;C deinit&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;f2&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;C&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// one allocation for C();&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;C init&quot; printed here;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// also increment its reference count by 1&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;reference1&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// increment reference count by 1 (2 in total)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;reference2&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;reference1&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;reference2&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// both `reference1` and `reference2` out of scope here;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// decrement reference count by 2;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// no deallocation because of a new reference created&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// for the return value outside of this function&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// increment reference count by 1, 1 in total&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f2&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// decrement reference count by 1, 0 in total&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;result&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;nil&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;C deinit&quot; printed here&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Swift doesn’t allow adding deinitialiser code to a &lt;code&gt;struct&lt;/code&gt; with &lt;code&gt;deinit&lt;/code&gt;, but
it’s possible for &lt;code&gt;class&lt;/code&gt;es, which allows us to better track deallocations. Now
memory management is a bit more involved. With this code,
you’re guaranteed only one allocation and no copies will occur, but this also
involves allocating storage for a counter that tracks all references. There’s
also runtime overhead now for incrementing and decrementing the counter. In
addition, reference counting in Swift is thread-safe, but this involves using
&lt;a href=&quot;https://en.wikipedia.org/wiki/Fetch-and-add&quot;&gt;atomic operations&lt;/a&gt;. This adds
even more potential runtime overhead when compared to optimised code using
only value types.&lt;/p&gt;
&lt;h2&gt;Ok, and what’s a reference cycle then?&lt;/h2&gt;
&lt;p&gt;Consider a tree-like data structure, where a node in this tree holds a reference
to its children. It would be nice for a node to also hold a reference to its
parent. Here’s a naive approach that expresses this with a class:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;TreeNode&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;private&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;children&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;]()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;private&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;TreeNode init&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;deinit&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;TreeNode deinit&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.append&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.parent&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;self&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;f3&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;root&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;TreeNode init&quot; printed here&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;for&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;3&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.add&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;())&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;TreeNode init&quot; printed here&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f3&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;TreeNode deinit&quot; printed 4 times here, no??? 🤔&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Well, here’s a problem: a child and a parent both hold references to each other,
which means their reference counts will never reach &lt;code&gt;0&lt;/code&gt;. So even if it looks
like all references to &lt;code&gt;TreeNode&lt;/code&gt; instances went out of scope when returning
from &lt;code&gt;f3&lt;/code&gt;, none of those instances were deallocated and you’ll never see
&lt;code&gt;&quot;TreeNode deinit&quot;&lt;/code&gt; printed even once!&lt;/p&gt;
&lt;h2&gt;How do I avoid reference cycles with classes?&lt;/h2&gt;
&lt;p&gt;Good news is that in Swift any variable of an optional class type can be declared
&lt;code&gt;weak&lt;/code&gt;. It will hold a “weak” reference to the instance without incrementing
its reference count. This also means that this reference becomes &lt;code&gt;nil&lt;/code&gt; when
the instance is deallocated, you can’t have “weak” constants because of this:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-comment&quot;&gt;// strong reference&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;node1&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;TreeNode init&quot; printed here&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// weak reference, reference count untouched&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;weak&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;node2&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;node1&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// deallocate what&apos;s stored in `node1`&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;node1&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;nil&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;TreeNode deinit&quot; printed here&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// what&apos;s referenced by `node2` then?&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;node2&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;nil&quot; printed here&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Now let’s fix our &lt;code&gt;TreeNode&lt;/code&gt; memory leak with a weak reference:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;TreeNode&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;private&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;children&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;]()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// note added `weak` added before `var parent`&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;private&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;weak&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;TreeNode init&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;deinit&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;TreeNode deinit&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.append&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.parent&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;self&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;f4&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;root&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;TreeNode init&quot; printed here&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;for&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;3&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.add&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;TreeNode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;())&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;TreeNode init&quot; printed here&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f4&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// &quot;TreeNode deinit&quot; printed 4 times here, yay! 🎉&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;You may have seen example code like above multiple times in many educational
materials about Swift. Memory management based on compile-time guarantees and
optimisations has these downsides that you need to be aware of. On balance it
pays off as performance impact is predictable and deterministic. In Swift, you
don’t need to worry that &lt;a href=&quot;https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)&quot;&gt;a garbage
collector&lt;/a&gt;
will unexpectedly pause everything in the middle of carefully optimised code
for deallocations. This becomes critical in code that has
anything to do with UI, especially AR/VR: you don’t want to drop rendered frames
in the middle of a user interaction, especially when you need to deliver 120
freshly rendered frames per second.&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;advanced&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Classes cause reference cycles, reference cycles are bad. Are classes bad?&lt;/h2&gt;
&lt;p&gt;Maybe it’s time to reconsider the situation: classes cause reference cycles, why
not stop using classes? And besides, &lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2015/408/&quot;&gt;protocol-oriented
programming&lt;/a&gt; is cool, we
can use &lt;a href=&quot;https://en.wikipedia.org/wiki/Composition_over_inheritance&quot;&gt;composition instead of
inheritance&lt;/a&gt;, use
structs, enums and protocols for everything, we don’t need those stinky classes
with stupid reference cycles! 😜&lt;/p&gt;
&lt;p&gt;Huh, that sounds quite attractive. Except that we forgot about yet another
important reference type in Swift: closures! Yes, &lt;a href=&quot;/closures#title&quot;&gt;closures are reference types&lt;/a&gt;, they need to capture the environment outside to allow modifying
that environment when a closure body is executed. This has the same implications
we’ve discussed previously: assigning a closure to a variable will increase the
reference count for that closure instead of copying it.&lt;/p&gt;
&lt;h2&gt;So what’s that kind of reference cycles no one’s talking about?&lt;/h2&gt;
&lt;p&gt;You can create a reference cycle with classes, you can create
a reference cycle with closures and classes, but you can’t create a reference
cycle with closures and value types, right?&lt;/p&gt;
&lt;p&gt;No, it turns out you can even create &lt;em&gt;unbreakable reference cycles&lt;/em&gt; with
closures and value types! 😱 The big problem here is that capturing a value (not
a class) in a closure implicitly creates a new reference to that value for
closure’s environment:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;i&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;0&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;increment&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;+=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;1&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// prints &quot;1&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;So even though &lt;code&gt;i&lt;/code&gt; is a value, not a class instance, &lt;code&gt;i&lt;/code&gt; inside of the closure
&lt;code&gt;increment&lt;/code&gt; is a reference to &lt;code&gt;i&lt;/code&gt; in closure’s environment. Not only &lt;code&gt;increment&lt;/code&gt;
stores a reference to the closure, but the closure itself also creates and
stores a new reference!&lt;/p&gt;
&lt;p&gt;You could say “just make these references weak”! Sure, that’s easy with a
closure environment that only captures class instances:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;I&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;x&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;0&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;i&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// explicit capture list for capturing `i` weakly&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.increment&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;weak&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;]&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.x&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;+=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;1&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.increment&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Cool, now &lt;code&gt;i&lt;/code&gt; holds a strong reference to the closure, but closure holds a weak
reference to &lt;code&gt;i&lt;/code&gt;, no reference cycle. Why not try the same with value types?&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;I&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;x&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;0&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;i&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.increment&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.x&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;+=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;1&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// reference cycle!&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.increment&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;What’s worse, if you add &lt;code&gt;[weak i]&lt;/code&gt; capture list to fix the reference cycle you’d
get a compiler error like &lt;code&gt;&apos;weak&apos; may only be applied to class and class-bound protocol types, not &apos;I&apos;&lt;/code&gt;. The only way to break the reference cycle is to
explicitly set &lt;code&gt;i.increment&lt;/code&gt; to &lt;code&gt;nil&lt;/code&gt; when it’s no longer needed, which is less
than ideal. 😞&lt;/p&gt;
&lt;h2&gt;Think twice before storing a closure as a property of a value type&lt;/h2&gt;
&lt;p&gt;Can we still avoid using classes with the caveat that we clean up our closures
manually? I don’t think so, here’s why:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;I&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;x&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;0&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;i&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.increment&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.x&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;+=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;1&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// reference cycle!&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;copy&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.increment&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.increment&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.increment&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.x&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// guess what&apos;s printed here? 🤨&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// break the reference cycle manually&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.increment&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;nil&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.increment&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;nil&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Guess what’s the value of &lt;code&gt;copy.x&lt;/code&gt; printed above? &lt;code&gt;0&lt;/code&gt;! You’d probably expect &lt;code&gt;3&lt;/code&gt;
and that &lt;code&gt;copy&lt;/code&gt; holds a copy of &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;copy.increment?()&lt;/code&gt; increments &lt;code&gt;copy.x&lt;/code&gt;.
But remember that closures and their environment can’t be copied. That’s why
&lt;code&gt;copy&lt;/code&gt; is a “partial” copy of &lt;code&gt;i&lt;/code&gt;. Value of &lt;code&gt;x&lt;/code&gt; has been copied, but property
&lt;code&gt;increment&lt;/code&gt; of &lt;code&gt;copy&lt;/code&gt; holds a reference to &lt;code&gt;increment&lt;/code&gt; of &lt;code&gt;i&lt;/code&gt; with &lt;code&gt;x&lt;/code&gt; of &lt;code&gt;i&lt;/code&gt; in
the captured environment. Calling &lt;code&gt;copy.increment?()&lt;/code&gt; will follow the reference
and increment value of &lt;code&gt;x&lt;/code&gt; on the original &lt;code&gt;i&lt;/code&gt; instead of &lt;code&gt;copy&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you find yourself writing code similar to above with value types holding
references to closures, take extreme care to avoid unexpected results.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;We’ve compared memory management with value and reference types in Swift and had
a look at different ways to create and break reference cycles. Reference cycles
between different class instances are trivial, but when you start using closures
this can get a bit more complicated. The most unexpected kind of reference
cycles involves closures and value types and most frequently you would want to
rearchitect code using those in a different way. In these situations breaking the
reference cycle requires manual handling and can cause subtle errors due to the
fact that the closure environment can’t be copied.&lt;/p&gt;
&lt;p&gt;Many thanks to &lt;a href=&quot;https://forums.swift.org/&quot;&gt;Swift Forums&lt;/a&gt; for giving an
opportunity to discuss these issues. I really enjoyed learning a lot of
interesting details about how references work (and could work in future versions
of Swift) in &lt;a href=&quot;https://forums.swift.org/t/avoiding-unbreakable-reference-cycle-with-value-types-and-closures/18757&quot;&gt;this Swift Forums
topic&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Are you interested in other memory management features of Swift? Have you been able to work around
these reference cycles in a different way? I look forward to hearing your story, please shoot a
message on &lt;a href=&quot;https://mastodon.social/@maxd&quot;&gt;Mastodon&lt;/a&gt; or &lt;a href=&quot;https://twitter.com/maxdesiatov&quot;&gt;Twitter&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Easy parsing of Excel spreadsheet format with Swift's Codable protocols]]></title><description><![CDATA[Back in the 90s and early 00s, when Google Docs didn’t exist yet and devices
from Apple weren’t as popular, the primary way to create, edit…]]></description><link>https://desiatov.com/swift-codable-xlsx/</link><guid isPermaLink="false">https://desiatov.com/swift-codable-xlsx/</guid><pubDate>Mon, 12 Nov 2018 12:40:32 GMT</pubDate><content:encoded>&lt;p&gt;Back in the 90s and early 00s, when Google Docs didn’t exist yet and devices
from Apple weren’t as popular, the primary way to create, edit and share
documents and spreadsheets was Microsoft Office and its proprietary &lt;code&gt;.doc&lt;/code&gt; and
&lt;code&gt;.xls&lt;/code&gt; binary formats. At that time working with these files outside of
Microsoft’s ecosystem was a world of pain, there were multiple attempts to
reverse engineer these formats, but none of them were good enough.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/Excel_2010-ea0c8b61f3c437e0ef0452e7739a3b00-13ec1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 57.41675075681131%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACBklEQVQoz62P228SQRTG99/xxSeNkS1CSRQviSmt/nM+GCMx0VKMtSmtFRQllItVskvRsMBe2GW57ALDQpdlL3McVts0tU/qSX453zkz8+Ub6nn65X5Vk0FQJ7g7Mi1Zm1pibzKvSwOr2WItQR0uuLZm852hLQ+m82ZnbEqDqanoJ6bUm5woujmrNlSLaWpwkC0kqcK39k6rD8DymlMTR8CKOnznu8A2+lCsNqDC9Qhd+FpXyZ0h5FkZmJYOdcWAUk0BhuwOWcn7ocxgL1vOUKXyx11DL0NblZ1Gx8AMr2NOGWFFm2FpMMPtwRRLfQOT1EQbmKTEbTIvkX53QUVub+JAMpVNU7lPiS3TaMF4rDuW7YG1sGG+cMC0SD8P2Z31U87ObBdIPd3c26YyJW5rOWCMHc/z4BR8QZ+fLzn/ZfgqtU19KFZ9Q891Hdd14S/xDZ8lSMJ04f8Z+l/ez1USvqHn2mSP/8Dz8MK28Xxu+fqyO8swS4/463d+wiT4heFfa3M3u0PF32TjBVZ0j46FYZ4RUK7SQgWGR6WaPCkey8inJpNZQYesiNJlDmW+NFE6f4RSOQYdFDn0vlQffa4Iiycv3iaoa4HIlZuRh8FgdD0QjMboW4TQvQ06dHfD18E7a0Svkx4LrNxeo8NERx48psORFfo6vUqTt4FQNBZYvf8oeIMOX/0Jrr36ljz05bkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Microsoft Excel 2010 running on Windows 7&quot;
        title=&quot;&quot;
        src=&quot;/static/Excel_2010-ea0c8b61f3c437e0ef0452e7739a3b00-fb8a0.png&quot;
        srcset=&quot;/static/Excel_2010-ea0c8b61f3c437e0ef0452e7739a3b00-1a291.png 148w,
/static/Excel_2010-ea0c8b61f3c437e0ef0452e7739a3b00-2bc4a.png 295w,
/static/Excel_2010-ea0c8b61f3c437e0ef0452e7739a3b00-fb8a0.png 590w,
/static/Excel_2010-ea0c8b61f3c437e0ef0452e7739a3b00-526de.png 885w,
/static/Excel_2010-ea0c8b61f3c437e0ef0452e7739a3b00-13ec1.png 991w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;center&gt;&lt;small&gt;Image from &lt;a href=&quot;https://en.wikipedia.org/wiki/File:Excel_2010.png&quot;&gt;en.wikipedia&lt;/a&gt;&lt;/small&gt;&lt;/center&gt;&lt;br/&gt;
&lt;p&gt;Fortunately, later Microsoft transitioned towards using an XML-based format:
&lt;a href=&quot;https://en.wikipedia.org/wiki/Office_Open_XML&quot;&gt;XLSX&lt;/a&gt;. Even now I occasionally
stumble upon a service that yields a file like this instead of a
&lt;a href=&quot;https://en.wikipedia.org/wiki/Comma-separated_values&quot;&gt;CSV&lt;/a&gt;. There is a plenty
of apps that open these files without Microsoft Office installed, even standard
QuickLook on iOS and macOS can give you a preview for it.&lt;/p&gt;
&lt;p&gt;But previews and apps are only ok for manual operations. What if there’s a need
for automation? For example, my specific use case is to transform an Excel
spreadsheet using only specific rows and columns into a CSV file with a subset
of columns from the original file. If you’re like me and would like to stay in
the Swift ecosystem, there are no great options. There’s an &lt;a href=&quot;https://github.com/renebigot/XlsxReaderWriter&quot;&gt;Objective-C
library&lt;/a&gt; that at the moment of
publishing this article hasn’t been updated in more than 2 years. There’s
another &lt;a href=&quot;https://libxlsxwriter.github.io&quot;&gt;C library&lt;/a&gt; that can create and write
XLSX files, but as far as I know, can’t read one. &lt;/p&gt;
&lt;p&gt;And implementing support for a file format is a huge and complex task, right?
There’s some compressed data involved, multiple entities to parse and there’s a
ton of variation in different files which is hard to support?&lt;/p&gt;
&lt;h2&gt;Easy peasy, it’s just an archive of XML files!&lt;/h2&gt;
&lt;p&gt;Turns out, an XLSX file is a simple zip archive, you can poke at its raw
content with a simple terminal command:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span &gt;$ unzip file.xlsx
Archive:  file.xlsx
  inflating: _rels/.rels             
  inflating: docProps/core.xml       
  inflating: docProps/app.xml        
  inflating: xl/workbook.xml         
  inflating: xl/_rels/workbook.xml.rels  
  inflating: xl/theme/theme1.xml     
  inflating: xl/worksheets/sheet1.xml  
  inflating: xl/sharedStrings.xml    
  inflating: xl/styles.xml           
  inflating: [Content_Types].xml &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;When there’s a need to get data out of a single worksheet, there are only 3
files to parse: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;_rels/.rels&lt;/code&gt; – this XML file stores paths to “documents” contained within the
main &lt;code&gt;file.xlsx&lt;/code&gt; archive&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xl/_rels/workbook.xml.rels&lt;/code&gt; – this file referenced from &lt;code&gt;_rels/.rels&lt;/code&gt;
contains paths of worksheets that documents in the archive have&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xl/worksheets/sheet1.xml&lt;/code&gt; – this is where worksheet data lives: rows,
columns and cells.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;What does “Codable” mean in Swift?&lt;/h2&gt;
&lt;p&gt;There are multiple ways to implement parsers for different formats. JavaScript,
for example, comes with a standard
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse&quot;&gt;&lt;code&gt;JSON.parse&lt;/code&gt;&lt;/a&gt;
function, which is able to parse JSON, but for any other format, you’re on your
own. All 3rd-party libraries for JavaScript like to invent their own parsing
APIs from scratch. &lt;/p&gt;
&lt;p&gt;This was even worse not so long ago with the first few
versions of Swift when we not only had ad-hoc APIs for other formats like XML
but dozens of JSON parsing libraries as well. 😅 But I’m so happy to deal with Swift
nowadays after it gained &lt;a href=&quot;https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types&quot;&gt;a standard
API&lt;/a&gt;
for almost any serialization format you’d need.&lt;/p&gt;
&lt;p&gt;The main concepts in this serialization API in Swift are the &lt;code&gt;Codable&lt;/code&gt;
typealias:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;typealias&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Codable&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Decodable&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&amp;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Encodable&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;and the &lt;code&gt;Decodable&lt;/code&gt;/&lt;code&gt;Encodable&lt;/code&gt; protocols:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;protocol&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Decodable&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;from&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;decoder&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Decoder&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;protocol&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Encodable&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;to&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;encoder&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Encoder&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;There are also &lt;code&gt;Encoder&lt;/code&gt; and &lt;code&gt;Decoder&lt;/code&gt; protocols mentioned above, but they
don’t really matter in the day-to-day use of &lt;code&gt;Codable&lt;/code&gt;. The most wonderful thing
here is that Swift compiler is able to derive an implementation of &lt;code&gt;Codable&lt;/code&gt;
for your types automatically, as long as &lt;code&gt;Codable&lt;/code&gt; implementation is available
on types of properties that you use. And obviously, &lt;code&gt;Codable&lt;/code&gt; is already
implemented on all primitive types like &lt;code&gt;Bool&lt;/code&gt;, &lt;code&gt;Int&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt; etc.&lt;/p&gt;
&lt;p&gt;Even better, implementation of &lt;code&gt;Codable&lt;/code&gt; on your types can be reused for
multiple formats if needed. For example &lt;code&gt;Foundation&lt;/code&gt; module provides standard
&lt;a href=&quot;https://developer.apple.com/documentation/foundation/jsonencoder&quot;&gt;&lt;code&gt;JSONEncoder&lt;/code&gt;&lt;/a&gt;
and
&lt;a href=&quot;https://developer.apple.com/documentation/foundation/jsondecoder&quot;&gt;&lt;code&gt;JSONDecoder&lt;/code&gt;&lt;/a&gt;
types that allow serialising your data in and out of JSON in a standard way.
But for our case, we only need a 3rd-party implementation of this for XML, like
&lt;a href=&quot;https://github.com/MaxDesiatov/XMLCoder&quot;&gt;&lt;code&gt;XMLCoder&lt;/code&gt;&lt;/a&gt;.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2&gt;“Codable” in practice&lt;/h2&gt;
&lt;p&gt;As shown earlier, our first step towards reading data from an Excel file is
parsing &lt;code&gt;_rels/.rels&lt;/code&gt; in the archive, which looks like this:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-tag bracket&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-tag&quot;&gt;Relationships&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;xmlns&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;http://schemas.openxmlformats.org/package/2006/relationships&quot;&lt;/span&gt;&lt;span class=&quot;cm-tag bracket&quot;&gt;&gt;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-tag bracket&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-tag&quot;&gt;Relationship&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;cm-attribute&quot;&gt;Id&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;rId1&quot;&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;cm-attribute&quot;&gt;Type&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties&quot;&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;cm-attribute&quot;&gt;Target&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;docProps/core.xml&quot;&lt;/span&gt;&lt;span class=&quot;cm-tag bracket&quot;&gt;/&gt;&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-tag bracket&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-tag&quot;&gt;Relationship&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;cm-attribute&quot;&gt;Id&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;rId2&quot;&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;cm-attribute&quot;&gt;Type&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties&quot;&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;cm-attribute&quot;&gt;Target&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;docProps/app.xml&quot;&lt;/span&gt;&lt;span class=&quot;cm-tag bracket&quot;&gt;/&gt;&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-tag bracket&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-tag&quot;&gt;Relationship&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;cm-attribute&quot;&gt;Id&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;rId3&quot;&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;cm-attribute&quot;&gt;Type&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument&quot;&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;cm-attribute&quot;&gt;Target&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;xl/workbook.xml&quot;&lt;/span&gt;&lt;span class=&quot;cm-tag bracket&quot;&gt;/&gt;&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-tag bracket&quot;&gt;&lt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-tag&quot;&gt;/Relationships&lt;/span&gt;&lt;span class=&quot;cm-tag bracket&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;The most primitive node we’d like to handle in a type-safe manner is &lt;code&gt;Type&lt;/code&gt;
of the &lt;code&gt;Relationship&lt;/code&gt;, let’s create an &lt;code&gt;enum&lt;/code&gt; for it (I’ve replaced long schema
urls with &lt;code&gt;[...]&lt;/code&gt; for brevity):&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;enum&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;SchemaType&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Codable&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;officeDocument&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;[...]/officeDocument&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;extendedProperties&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;[...]/extended-properties&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;coreProperties&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;[...]/core-properties&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;worksheet&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;[...]/worksheet&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;sharedStrings&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;[...]/sharedStrings&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;styles&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;[...]/styles&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;theme&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;[...]/theme&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;&lt;small&gt;A complete version is &lt;a href=&quot;https://github.com/MaxDesiatov/CoreXLSX/blob/master/Sources/CoreXLSX/Relationships.swift#L19&quot;&gt;available on GitHub&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Note the &lt;code&gt;Codable&lt;/code&gt; conformance on this &lt;code&gt;enum&lt;/code&gt;, we don’t need to implement
anything for it manually as it will be generated automatically by the compiler
for us. The next step is the &lt;code&gt;Relationship&lt;/code&gt; node itself:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Relationship&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Codable&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;SchemaType&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;And then it’s only the root &lt;code&gt;Relationships&lt;/code&gt; node left:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Relationships&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Codable&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Relationship&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;]&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;enum&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;CodingKeys&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;CodingKey&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;items&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;relationship&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Note the &lt;code&gt;CodingKeys&lt;/code&gt; enum here conforming to the
&lt;a href=&quot;https://developer.apple.com/documentation/swift/codingkey&quot;&gt;&lt;code&gt;CodingKey&lt;/code&gt;&lt;/a&gt;
protocol. It allows us to specify a different name for a property that contains
the decoded data. In our case, there are multiple &lt;code&gt;Relationship&lt;/code&gt; children nodes
within the root &lt;code&gt;Relationships&lt;/code&gt; node. It’s better when these nodes are stored
in a property named &lt;code&gt;items&lt;/code&gt; rather than a default &lt;code&gt;relationship&lt;/code&gt; property
you’d have to create without &lt;code&gt;CodingKeys&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The main property we’re interested in here though is the &lt;code&gt;target&lt;/code&gt; on a
&lt;code&gt;Relationship&lt;/code&gt; node with type &lt;code&gt;officeDocument&lt;/code&gt;, it contains a path to the
document. But also, remember that all of this XML is stored within a zip
archive, how do we unzip it in the first place?&lt;/p&gt;
&lt;h2&gt;Unzipping an archive in memory and parsing the contents&lt;/h2&gt;
&lt;p&gt;A great indicator of Swift ecosystem maturity is the number of good libraries
you can find for the most popular tasks when working on production
apps. And it’s pretty good, well, except for XLSX libraries until now. 😂
But at the moment we also need to uncompress a zip archive in memory and it
looks like &lt;a href=&quot;https://github.com/weichsel/ZIPFoundation&quot;&gt;ZIPFoundation&lt;/a&gt; is the
best implementation that supports both Linux and Apple platforms.&lt;/p&gt;
&lt;p&gt;Let’s create the main entry point for the public API of our XLSX library:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;XLSXFile&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;The main type we need to work in &lt;code&gt;ZIPFoundation&lt;/code&gt; is &lt;code&gt;Archive&lt;/code&gt;, let’s
add it as a private property and also create an instance of &lt;code&gt;XMLCoder&lt;/code&gt; to reuse
later:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;XLSXFile&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;filepath&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;private&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;archive&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Archive&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;private&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;decoder&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;XMLDecoder&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;filepath&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;archiveURL&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;fileURLWithPath&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;filepath&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;guard&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;archive&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Archive&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;archiveURL&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;accessMode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.read&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;else&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;nil&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.archive&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;archive&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.filepath&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;filepath&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;decoder&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;XMLDecoder&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Now we also need a generic way to parse an XML file from the archive, let’s
add a function on &lt;code&gt;XLSXFile&lt;/code&gt; and also a helper &lt;code&gt;Error&lt;/code&gt; subtype for it.
This &lt;code&gt;parseEntry&lt;/code&gt; function should take a path like &lt;code&gt;_rels/.rels&lt;/code&gt; and a type
of representation of a root node and return an instance of that type or throw
an error:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;enum&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;XLSXReaderError&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Error&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;archiveEntryNotFound&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;XLSXFile&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;private&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;archive&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Archive&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;private&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;decoder&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;XMLDecoder&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Parse a file within `archive` at `path`. Parsing result is&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// an instance of `type`.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;parseEntry&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Decodable&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&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;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.Type&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;guard&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;entry&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;archive&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;]&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;else&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throw&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;XLSXReaderError&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.archiveEntryNotFound&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;archive&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.extract&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;result&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;decoder&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.decode&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;And now we can use this function to get the list of documents within
the archive. Here &lt;code&gt;.convertFromCapitalized&lt;/code&gt; setting specifies we’d like
to convert capitalised attribute names to lowercase properties so that &lt;code&gt;Target&lt;/code&gt;
becomes &lt;code&gt;target&lt;/code&gt;, &lt;code&gt;Type&lt;/code&gt; becomes &lt;code&gt;type&lt;/code&gt; and &lt;code&gt;Id&lt;/code&gt; is mapped to &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;XLSXFile&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Return an array of paths to relationships of type `officeDocument`&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;parseDocumentPaths&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;]&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;decoder&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.keyDecodingStrategy&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.convertFromCapitalized&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;parseEntry&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;_rels/.rels&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Relationships&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.self&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.items&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.filter&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.type&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;==&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.officeDocument&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.map&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.target&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;h2&gt;Parsing a worksheet&lt;/h2&gt;
&lt;p&gt;I omit a completely boring 20-line function &lt;code&gt;parseWorksheetPaths&lt;/code&gt; where we parse
a similar relationships file to get paths to the actual worksheets. While this
function is going to be used later, it’s very similar to &lt;code&gt;parseDocumentPaths&lt;/code&gt;
we’ve just implemented above. Instead, let’s focus on a much more interesting
model type &lt;code&gt;Worksheet&lt;/code&gt;:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Worksheet&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Codable&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;sheetPr&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;SheetPr&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;dimension&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;WorksheetDimension&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;sheetViews&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;SheetViews&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;sheetFormatPr&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;SheetFormatPr&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;cols&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Cols&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;sheetData&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;SheetData&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;mergeCells&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;MergeCells&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;This type directly represents a worksheet XML you’ll be able to find in most
common XLSX files. Basically, the rest of the source code of the parsing
library is &lt;code&gt;struct&lt;/code&gt; declarations of the property types you find on the root
&lt;code&gt;Worksheet&lt;/code&gt; XML node and the rest of the types match its descendant nodes.
For example, one such type is &lt;code&gt;Cell&lt;/code&gt;:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Cell&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Codable&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Equatable&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;reference&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;inlineString&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;InlineString&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;formula&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;enum&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;CodingKeys&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;CodingKey&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;formula&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;f&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;value&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;v&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;inlineString&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;is&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;reference&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;r&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;type&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;t&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;case&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;s&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;And sorry I don’t know what exactly the attribute &lt;code&gt;s&lt;/code&gt; stands for &lt;code&gt;¯\_(ツ)_/¯&lt;/code&gt;.
It’s still not easy to find detailed documentation on all of the attributes, but
I’ve been able to provide sensible names to most of them.&lt;/p&gt;
&lt;p&gt;For some reason worksheet XML nodes and attributes aren’t capitalised, so we
need to reset the decoding strategy for parsing them to &lt;code&gt;.useDefaultKeys&lt;/code&gt;. This
will leave node and attribute names lowercase as they are.&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;struct&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;XLSXFile&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;private&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;decoder&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;XMLDecoder&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Parse a worksheet at a given path contained in this XLSX file.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;parseWorksheet&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;at&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;throws&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Worksheet&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;decoder&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.keyDecodingStrategy&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.useDefaultKeys&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;parseEntry&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Worksheet&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.self&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;h2&gt;Using the library&lt;/h2&gt;
&lt;p&gt;Now we’ve got the library working, let’s read a simple file:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;guard&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;file&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;XLSXFile&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;filepath&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;./file.xlsx&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;else&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;fatalError&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;XLSX file corrupted or does not exist&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;for&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;path&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.parseWorksheetPaths&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;ws&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;try&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.parseWorksheet&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;for&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;row&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.sheetData.rows&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;for&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;c&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.cells&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;This will print every cell in every worksheet in an XLSX file provided.
And that’s mostly all there is to it. 🙌&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;It seems like there are no cross-platform libraries for parsing XLSX available
to use with Swift. Turns out, implementing file format support from scratch
isn’t that hard with the great
&lt;a href=&quot;https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types&quot;&gt;&lt;code&gt;Codable&lt;/code&gt;&lt;/a&gt;
API available in Swift standard library. XLSX files are actually zip archives
with multiple XML files within. In this article, we had a look at the code that
decompresses an archive in memory and parses the XML files to get cell data for
any given worksheet. &lt;/p&gt;
&lt;p&gt;I’ve published this as &lt;a href=&quot;https://github.com/MaxDesiatov/CoreXLSX&quot;&gt;&lt;code&gt;CoreXLSX&lt;/code&gt;&lt;/a&gt;
package available to use with &lt;a href=&quot;https://cocoapods.org&quot;&gt;CocoaPods&lt;/a&gt; and &lt;a href=&quot;https://swift.org/package-manager/&quot;&gt;Swift
Package Manager&lt;/a&gt;. I hope this library saves
you some time when you need to read something from an XLSX file in an automated
way. Or maybe you could use it as an example for implementing other file formats
in your apps and libraries. Either way, I’d appreciate your feedback on
&lt;a href=&quot;https://twitter.com/maxdesiatov&quot;&gt;Twitter&lt;/a&gt; or
&lt;a href=&quot;https://mastodon.social/@maxd&quot;&gt;Mastodon&lt;/a&gt; and would be very happy if you star
the repository and create issues and pull requests &lt;a href=&quot;https://github.com/MaxDesiatov/CoreXLSX&quot;&gt;at GitHub&lt;/a&gt;. 🤩&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;  This library is a hard fork of a great
&lt;a href=&quot;https://github.com/ShawnMoore/XMLParsing&quot;&gt;&lt;code&gt;XMLParsing&lt;/code&gt;&lt;/a&gt; package by &lt;a href=&quot;https://github.com/ShawnMoore&quot;&gt;Shawn
Moore&lt;/a&gt;. Unfortunately, it looks like the
original repository doesn’t accept PRs for known issues and &lt;a href=&quot;https://github.com/ShawnMoore/XMLParsing/issues/20&quot;&gt;hasn’t been
updated in some time&lt;/a&gt;.
&lt;a href=&quot;https://github.com/MaxDesiatov/XMLCoder/commit/6d147739c7aa52b6b6d7ec5fd0d58740397ee233&quot;&gt;Some of these
issues&lt;/a&gt;
were blocking my XLSX parsing implementation. To make matters worse, CocoaPods
doesn’t allow dependencies on forks with the same name as original libraries,
so I had to create a fork with a new name. I wish I could merge my
contributions back. 😔&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Event loops, building smooth UIs, and handling high server load]]></title><description><![CDATA[This article is a part of my series about concurrency and asynchronous
programming in Swift. The articles are independent, but after reading…]]></description><link>https://desiatov.com/event-loops/</link><guid isPermaLink="false">https://desiatov.com/event-loops/</guid><pubDate>Thu, 16 Aug 2018 12:40:32 GMT</pubDate><content:encoded>&lt;p&gt;This article is a part of my series about concurrency and asynchronous
programming in Swift. The articles are independent, but after reading this one
you might want to check out the rest of the series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;&lt;a href=&quot;/closures#title&quot;&gt;How do closures and callbacks work? It’s turtles all the way
down&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Event loops, building smooth UIs, and handling high server load&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;&lt;a href=&quot;/swift-structured-concurrency-introduction#title&quot;&gt;Introduction to structured concurrency in Swift: continuations, tasks, and
cancellation&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;p&gt;Have you ever used an app that felt unresponsive? Not reacting to input on time,
slow animations even for some simple tasks, even when there isn’t anything heavy
running in the background? Most probably, an app like that is waiting for some blocking
long-running computation to finish before consuming more user input or rendering
animation frames. Scheduling all workloads correctly and in the right order
might seem hard, especially as there are different approaches to choose from.&lt;/p&gt;
&lt;h2&gt;What does it mean to be “non-blocking”?&lt;/h2&gt;
&lt;p&gt;When developing native apps for iOS, we always have this thesis: “avoid blocking
the main thread”. Due to the fact that UIKit and AppKit APIs are not
thread-safe, most if not all UI rendering happens on the main thread. If you
have a long-running blocking computation on that thread, your app isn’t able to
respond to user input or to render UI updates.&lt;/p&gt;
&lt;p&gt;For an app to feel smooth and interactive on a device with 60 Hz display refresh rate,
it has to render 60 frames a second and update those in response to user input
as close possible to real time. That means you as a developer only have
about 16.6 milliseconds of run time in event handlers on the main thread to
complete. Want the app to feel smooth on 120 Hz iPad Pro? That’s 8.3 milliseconds on
the main thread at your disposal.&lt;/p&gt;
&lt;p&gt;Here’s a conceptual diagram of CPU load on the main thread that refreshes UI
at 60 Hz and runs a blocking operation on the main thread. Red solid spikes in
CPU load are caused by UI rendering code, while blue ones are caused by HTTP
client code.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ui-io-bound-6abdcf189e7f84ffeb75207057be6a01-53c32.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 90.02000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAAsTAAALEwEAmpwYAAADB0lEQVQ4y31UyW4TQRDNByPxC3Dhwg2JW25cOHBAEMKOCEsExHZCQkw2x3ZiO048nn3r7pl5vOqxY4OAlkpdvb3aXtdKVVWQEWQGZ16GvYsYO8MIjUGIo0mC3VEEN9EYhwr749hKmBc4nqQY+Ll9O8eQeaWcLc69HF/6AV4cTPHycIq1nw4a5yHW2g76NOTT4JtjF8+433FSbHQ8tGh0GUyGBfxOL5o8/HYW4HPXx0fK3kWEH/RGjMjDzZ6PzjTFz8vEGtzhG9nfotHXRy69NjWgIJ95CpPYWOm6OU758Gqmd5wMo0Bxr54vI4YfKQypu4mxe103Q27KhYdRFsONA4qPXGf2wPUCqLzOESCXq9n8NykWOSzKAkeXQxxcnGN/2MfQm9pDLwoRpjENpP+VTCVI8rAGxAxwd9BFo3eE7bMTnLsTGi3Rv4pwyHyZhB6bAhWlzJV1tFK6BlhaV0XtJQFLtEd97FMuQw/KaOJVyJVhXgoYY1DxjkhB3RQllDa8V/KOtmsLNq+yoYfHDLnnjJFpdZ2LqqrzVhKoplaFWBW26l/Jhm1ydePUZ/UDaAIW5QwQS2POpWV9ztMBq9lmCkLyMdMFUopQ6EM34AdIWX21ANQMTUS8MoVCQYtaKRitkWfMIaMYOCH2hoH1smCYApoxLYcXPguY2pCrOW0OR2O0un2CarvpDwbovX6HYfsAJ2/fY9xs4eHd+9jYalsvFI1nTFvJnN68vYrW43UgTRfElhyk9EhLAbgZjUY4ef4KJ1tN7D9ZR//zJh7cuYen7xuknIbrB5iQp1PHwY1bq2g+egokSe2hAJ5eTdDo9DCYujb5En4Up1AMN05ShBGJ70eYUKZ+CC8ILaBDfRqQq2m2CFkAjeSMIhWVIRVzGVPArjLmV4t0aS+nhpWmHqryWg/y+uz6p+CPUVOmQpf/+RWbgDQF+fhiRDrMJzaOd+w628PQtjbpPMLFa8A5wLLMR0byzteKj6RPSif6QP4JDwUsyovfHFlZBlme/8VJU9aiaUC4KPPyu1+B1GFm3yKVuQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;UI rendering timeline example&quot;
        title=&quot;&quot;
        src=&quot;/static/ui-io-bound-6abdcf189e7f84ffeb75207057be6a01-fb8a0.png&quot;
        srcset=&quot;/static/ui-io-bound-6abdcf189e7f84ffeb75207057be6a01-1a291.png 148w,
/static/ui-io-bound-6abdcf189e7f84ffeb75207057be6a01-2bc4a.png 295w,
/static/ui-io-bound-6abdcf189e7f84ffeb75207057be6a01-fb8a0.png 590w,
/static/ui-io-bound-6abdcf189e7f84ffeb75207057be6a01-526de.png 885w,
/static/ui-io-bound-6abdcf189e7f84ffeb75207057be6a01-fa2eb.png 1180w,
/static/ui-io-bound-6abdcf189e7f84ffeb75207057be6a01-08f6a.png 1770w,
/static/ui-io-bound-6abdcf189e7f84ffeb75207057be6a01-53c32.png 5000w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;As you can see, if an HTTP client operation is blocking and runs for more than
33 milliseconds, up to 3 UI frames would not be rendered. Imagine
if the request runs on a slow network and takes seconds to complete, the app
UI would freeze and be unresponsive during all that time.&lt;/p&gt;
&lt;p&gt;The important thing to note on the diagram is that CPU stays idle while
waiting for the network operation to complete, so in principle, it could have
rendered the frames while waiting. This type of operation is called
&lt;em&gt;&lt;strong&gt;I/O-bound&lt;/strong&gt;&lt;/em&gt;, which means that a bottleneck in the operation is I/O
(filesystem access, networking, communicating with sensors and peripherals etc)
rather than intensive computations on the CPU. On the contrary, operations where
CPU load is a bottleneck are called &lt;em&gt;&lt;strong&gt;CPU-bound&lt;/strong&gt;&lt;/em&gt; operations. This distinction
is quite important, it turns out it’s quite easy to make I/O-bound code
non-blocking.&lt;/p&gt;
&lt;h2&gt;Event loops&lt;/h2&gt;
&lt;p&gt;How do people avoid blocking the main thread with I/O-bound code? Here’s one
approach: as soon as main app initialisation has finished, an event loop is
started (also known as a &lt;a href=&quot;https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html&quot;&gt;“run
loop”&lt;/a&gt;
in Cocoa/Foundation/GCD world). It is a loop that processes I/O events and
invokes corresponding event handlers at each iteration. While the loop is not
truly infinite, certain exit events, say a user closing the app, would clean up
the resources and stop the loop. But it’s indefinite in a sense that usually
there’s no predefined number of iterations when it starts.&lt;/p&gt;
&lt;h2&gt;Building smooth UIs&lt;/h2&gt;
&lt;p&gt;Most of the code an iOS/macOS developer writes is called from an event loop
iteration. All gesture recognisers, sensors input and higher level event
handlers such as button taps and navigation handlers are invoked on the main
thread and are scheduled by an event loop. This is applicable to browser apps
too: all your code (except web workers) runs on the same thread and blocking
computations would make UI freeze. In the end, the browser is just a native
application with its own event loop that forwards native events to your
JavaScript code.&lt;/p&gt;
&lt;p&gt;Here’s an example of a stacktrace of a native iOS app, which shows event loop
functions at the bottom of the stack:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/cfrunloop-d2ff8a2585098f726e7ff7047ce353dd-93b9a.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 100.43290043290042%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAADT0lEQVQ4y01U2bLcJhSc//+wVCVOruNcz6IRILRvIJA0fu70QRrbD13nIBVNn/XincO354Drw8AYA1uWqOsGVVmjKCyqukbbdeiHAU3TIsSI1+sHtv1F0NLff8PFzRO6ecOXa438meF6uyN7PvHMnlBK4/54kLDHEgIvvLAL0bYnrCfSed/5b8fl9drRzxFXM8AohWeukAvoC+Gb9JFl6Pr+VCjEG9Z1xbZG2pis4CKsbl5hSdi0DaytUJZVCrVpW5RVjYqwVXWko2nQdS2cm6mMZDEQy2kDLiJ1IWFTjCSpkjqtDQprE4FYrXX6Lrl1zPk4jlgWn5RFpiKG5UQ4FPopolQ9WiqytkxESSGLYIqCZ5u+i/KkkKF776nwCPuNGM+QPRXWdkTd1tCm+KmuZJhCqM/qy3chFYUdCyXF6vqB/kB/wBLXXwor5rDtqYiEh6qDUJSKlVy+1csDhi0lj2tjSTrC+cCCbb8UlpqvDd1RABbmffmtyoolsdIHmWCaPXxYkzIhi+suRdlIGFNRur5Ll6WhzRl6UkOSkuSiXLFAUqSksOA3Pi4QX1QmQjcHNHZiHo6QRZkg+SQVkhSqPqZJHsnZn8bIvyLlbxjnI2Sp1EE4oumadEkuiEpRIipFWZ7n6Sz/FJs+K1p8FhP+VQPKYUPebehdIlwxj2wbTcKmToreCvWpMIUoqtiLhT17s5nwbFc8mkgbca8DavJcVhK6eUFp29RvcrksbYLRCj3TMDC3YgXSwDsbWvJVD5yUsCMIGG6QtpHhXhxbps5RchIkX4aFyYsKN2XxrDqq4Zy37FMXCU4V8ZfxuFFdzcUyLzHN+BKSwg3NOOE7k/yhWvzxmePPK/1Hga9caR+3HF/vOVecwU2XuJsaN1PhzhyKb3qP1h1TIqSXsG7MwciQM7TMYV0VJywC5zVy8Lc1YKONi8PiXZpjmemZ8MuCnKHHGA7CyBnU3YjbU1SU+Lhr/HNX+Pum8JGxuv2CYlpRMOFmXKGGlQREf9isj/RPwhQyCd3ooDLmTFt8Y3j/PRQ+Hzn3pEtTMLEAo2chFlFxQBau53n2YmM6h7S+WLFuXPA9a1AoLlHuRM9dN0/jsZJi/Lnr4m9kjiQzH5n8Yd1J+j+L4sQ2FP3/xwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;CFRunLoop stack example&quot;
        title=&quot;&quot;
        src=&quot;/static/cfrunloop-d2ff8a2585098f726e7ff7047ce353dd-fb8a0.png&quot;
        srcset=&quot;/static/cfrunloop-d2ff8a2585098f726e7ff7047ce353dd-1a291.png 148w,
/static/cfrunloop-d2ff8a2585098f726e7ff7047ce353dd-2bc4a.png 295w,
/static/cfrunloop-d2ff8a2585098f726e7ff7047ce353dd-fb8a0.png 590w,
/static/cfrunloop-d2ff8a2585098f726e7ff7047ce353dd-526de.png 885w,
/static/cfrunloop-d2ff8a2585098f726e7ff7047ce353dd-fa2eb.png 1180w,
/static/cfrunloop-d2ff8a2585098f726e7ff7047ce353dd-08f6a.png 1770w,
/static/cfrunloop-d2ff8a2585098f726e7ff7047ce353dd-93b9a.png 2079w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;center&gt;&lt;small&gt;There&apos;s always an event loop there near the bottom of the call stack for UIKit apps.&lt;/small&gt;&lt;/center&gt;&lt;br/&gt;
&lt;p&gt;I bet, in 90+% of the cases when debugging the main thread of
iOS apps, you’d see these calls at the bottom of a stacktrace. It’s an implementation
detail that’s hidden quite well from us, but a very important one.&lt;/p&gt;
&lt;p&gt;How would an event loop fix our UI example with a blocking HTTP client? We saw
from the CPU load on the diagram that this operation is composed of two
parts: forming a request and parsing a response. Quite simply, we could run
request formation as soon the operation starts and then schedule response parsing
on a subsequent event loop iteration to be called only when this response is ready.&lt;/p&gt;
&lt;p&gt;Here’s a diagram of the same UI example with an event loop:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ui-event-loop-71a4e4509819aa4ac8851f4b4c643cce-53c32.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 104.03999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAAAsTAAALEwEAmpwYAAADTUlEQVQ4y3VVWW/bRhDm/39snwsYfUlRNEARNG3ixmjrpI0NWwJsw1Ys2xIlUxR1kRTvvfh1ZqmDUd0lBrM7u/vt3HRAo65rS9u5NnuS2kCZZl/pRmbqhrbzukXOFog3bqYZPg1jnA5ivO0t8Xs/xJvbJY6JPywKuGFp5ZfPCZ5WBU4eQjwtC7SHs9WKtfDiCv66wjNxvjygS7xm+SKTqJTBNBGWeM17YS53llgNGZAvvL9f4c+nCOfjNeapwDGtO16Cs9EafzxGVpNrP0WXZJ9Jxla8vpnjimQfac53lwRuATPBL0vMUomoUJaGYWXl86yRN2cEVrmCT3wUVejNcqvpkmQByXKh4bDvKsmLwpLSyvoijhOUZcneJdJkjt7NG27261rtfaiNxv3Uw43n4nYywni1sBtpkaESOaQq6cECQjb8JcqrhILKPiRAYwyungfouA+49oYEOKeHNWZhbiOrK8lRg5HKcqgW57QRG16JrYYG/WCCO39kwZKyAD+yziqsMgFFQDW9brSGUJo0F6S1Rl5Ku65JzueNasx2FGnT88cYLKZIq3KXk6QGvkp6ooyc3p2kNhNugqwB3OybTT477aRsZzy/esh5cI5yAYRFo9Gucjb7Tn1QOlvgQ0D2qxIlCiGQlqXNjJLm0LKxqg14OOoN6N58YEJVMVjmEJuK4K+UGh0y32prZRuTBTmUiV/RRtoAKNlwKTjKBo/BGhduhIiCpemspn1BAeuOQtwHibXAArIGd56Py4FLJtBh+rIgQHDRQehNMP7rE2LXxfF3r/Dmx3fIez1Muld4Jnk6cvHr0U/4eHIG7ft7k5OixDJJG59wKfpT+P+cYzF0MXj3AVG/j1++PcKro58RdboYn19i+P4E8eMDfvjme/z29hTG8/aAXwjgtNcns2a2lMqKcjBMkKZUq8sIYZQgmK0wW0RIqSSTdYoVySOaLxchomhN1af2gGlJjYBAKtlEjFuZ3sSKj1FfsP55ooZxHRTo+hlu59TeaN31c8SV2WWHgxdirCiS9/Pc5hu3LG5vHMU7SuYLiurf1ITPRrFtbedE3BN3gC/lISfrLV3m9rQuFQqprXz7O2DO6cMNl+dopZnTrpI2/4/e/yM/vPsvPjZOT0ewSiMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;UI rendering timeline example&quot;
        title=&quot;&quot;
        src=&quot;/static/ui-event-loop-71a4e4509819aa4ac8851f4b4c643cce-fb8a0.png&quot;
        srcset=&quot;/static/ui-event-loop-71a4e4509819aa4ac8851f4b4c643cce-1a291.png 148w,
/static/ui-event-loop-71a4e4509819aa4ac8851f4b4c643cce-2bc4a.png 295w,
/static/ui-event-loop-71a4e4509819aa4ac8851f4b4c643cce-fb8a0.png 590w,
/static/ui-event-loop-71a4e4509819aa4ac8851f4b4c643cce-526de.png 885w,
/static/ui-event-loop-71a4e4509819aa4ac8851f4b4c643cce-fa2eb.png 1180w,
/static/ui-event-loop-71a4e4509819aa4ac8851f4b4c643cce-08f6a.png 1770w,
/static/ui-event-loop-71a4e4509819aa4ac8851f4b4c643cce-53c32.png 5000w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;A notable change here is the introduction of callbacks. Instead of performing an
I/O-bound operation all at once, it is split into multiple parts, which are
chained with a callback. For example, in Swift a callback could be created in a
form of a closure:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;session&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;URLSession&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.shared&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.dataTask&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;https://your.api/call&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;error&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;br /&gt;
or a delegate object:

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Delegate&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;URLSessionTaskDelegate&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;urlSession&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;URLSession&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;URLSessionTask&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;didCompleteWithError&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;task&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.dataTask&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;https://your.api/call&quot;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.delegate&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Delegate&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;br /&gt;
or even with target-action pattern (usually reserved for UI handlers):

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Controller&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;UIViewController&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;viewDidLoad&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.viewDidLoad&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;button&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;UIButton&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.custom&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.addTarget&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-builtin&quot;&gt;#selector&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;),&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;                     &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.touchUpInside&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.addSubview&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;@objc&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;br /&gt;
All of these patterns are enabled by event loops. On a higher level, the
existing event loop is able to invoke these callbacks at some later iteration
without blocking other code.
&lt;h2&gt;Handling high HTTP server load&lt;/h2&gt;
&lt;p&gt;Even if you aren’t working on the full stack, as a frontend dev you might be
interested how those servers can handle the increased amount of requests from
your smooth apps powered by event loops. And if you’re a backend dev, I hope
that previous section was not too boring and you like this one even more. 😄&lt;/p&gt;
&lt;p&gt;Now imagine an HTTP server processing a high amount of requests coming at the
same time. Firstly, a request is parsed to get a few parameters and then the
server issues a query to a database with the parameters. After the query is
finished, a response is formed with the query result and sent to a client.&lt;/p&gt;
&lt;p&gt;It’s easy to see with an abstract CPU load diagram how a blocking database query
can kill the server’s throughput. On the following diagram there are three
separate CPU load spikes for every request and response sequence:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/server-io-bound-3de23d4749a137001687c6941d6fcc17-53c32.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 104.24%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAAAsTAAALEwEAmpwYAAADXUlEQVQ4y31UW4scRRTef+qTD/rggywE9yWgxjdZWMFLIA+CD8pGEIUQEWJIVMKuRohZdzezc+mZnZ5Lz/S1+lJdXf35VfX0XFxNwZnqqjrnO7fvzB62ltI1RmGBF67Ay6lovicCc1Gi42X4c5xgGBSYxhJnfDe7WXVdr/e99tACPr9O8Es/xPksJXCCZ06EuFDoLDL8fBXwPbb3T3ohLufp2rbFsYAnwxiPuwF+euXj4eUSj2hoIjwdxfhtEFkQ89YlqHH2lGDmzdj9SP3vzzw4Qd4Amp8hD+OowDVTvKJRb5ljmVUYhhIDP4fL1BymOktKuJGExxIYXVMKo2vKEWRqA/hfaxlEiKLEJEPRr5Hmva7VpoauH2K4WGKZCAtWaY04TRAmEYoyp2RbO0XlG+E5kwIijzY19OLEgknVhI2qQiWagivjhM2q0gx1pdd3Khb2DlrvNGbPRDPwFrhe+riaztGbe4gMGEGtUlmipk7FXa+MVVGgMiKlfWvBLKDmz2jho0+g8/HEAgdpiiBJMZr58BmJUay2IjE2egWwLa9tysveGM/Ouui5HhSjzQsJWSoGrm2k21Kt9huAjSdYEXmBOGPRZUlAjZKghVT2uyCwAdf/inzdZZ81m4aRbYqqJJUUUoJZBzTI8hwRGycJHkSxfYtpE7IcparIBnZZZE2ExsOcSiPWLmVadS2xSBLc++gIkTu2Sl8/eoAP3jlA9+IF3jp4DyfH3+HTH77F0f77QJHgw7uf4fiTe5aTNsKE6XlxvOahT2+f3/4Yi0Hfnu8+uI/bb+7j4q/f8cb+uzj56hh3vvkSh28fkD4L3Do6xP3DLxpATY6N/QCdyQy9mWfTlaXEnN8JnaRCwJlM4I6n8DwPHWeEOenVGY7gUcedzuCQHRExTPFvdLn986EfTkCJnI1I0gIRReRy1aCaTtkk1q9UesfWpmwKa+pnWt/ySfHu+aWD0/M+AXNLlyVn+8JhtF7ARhX2rhmsakNsQ4e/r10r5Wo6WgqYhhkOthzLGfFg4kFkhQ2nBdFb02InxfBNcJSMgdnLdqZXK8rSBrgmhcrC3oWpaBzqyr6vAU1Up90+/ug5eHrxCr9eXllOtiNm91Up1iNY797tRGjrVem1cmlTrHcG/mbj/v/uH8HHRq2DdPLRAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Server-side blocking IO example&quot;
        title=&quot;&quot;
        src=&quot;/static/server-io-bound-3de23d4749a137001687c6941d6fcc17-fb8a0.png&quot;
        srcset=&quot;/static/server-io-bound-3de23d4749a137001687c6941d6fcc17-1a291.png 148w,
/static/server-io-bound-3de23d4749a137001687c6941d6fcc17-2bc4a.png 295w,
/static/server-io-bound-3de23d4749a137001687c6941d6fcc17-fb8a0.png 590w,
/static/server-io-bound-3de23d4749a137001687c6941d6fcc17-526de.png 885w,
/static/server-io-bound-3de23d4749a137001687c6941d6fcc17-fa2eb.png 1180w,
/static/server-io-bound-3de23d4749a137001687c6941d6fcc17-08f6a.png 1770w,
/static/server-io-bound-3de23d4749a137001687c6941d6fcc17-53c32.png 5000w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;While HTTP servers don’t drop UI animation frames like in the UI example, a
blocking operation makes a client wait in a queue for a response until requests
are processed one by one. Of 6 requests shown, only 4 were handled by the end of
the diagram timeline. Again, it’s obvious that a database query is I/O-bound and
you could have processed many requests simultaneously. This would also saturate
CPUs more efficiently, which is quite important in reducing the cost of running
servers.&lt;/p&gt;
&lt;p&gt;You probably have guessed by this point, event loops come to the rescue! 😄 What
if the server started parsing a response as soon as it’s received, not waiting for
a database query of a previous request to complete? As I’ve marked three steps
of the operation in different colours, you can see that parts of asynchronous
request handling are executed out of order on a linear CPU timeline. It doesn’t
mean anything’s wrong, as HTTP is a stateless protocol, you can assume that
requests are independent and can be processed simultaneously.&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;server-event-loop-diagram&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/server-event-loop-ab34e08e11d5318628f70921613bba89-53c32.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 590px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 120%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAYAAAD6S912AAAACXBIWXMAAAsTAAALEwEAmpwYAAADuUlEQVQ4y31Va4scRRSdX+unSCDCisIixv3imiAaJCKoBDEfhCi+l4BGJMEHmocbd1nXndfO9Dz7Uf2q6uqqPt5bvd0zOxtzh0tVdVWduvfcUzUdkFVVdc6NrWCpZeO2tPW3Zm1jdmMfe2d9QWkqPPES3P0nwG9D4fo/HAeYJYXrf3fo49eBQNfPXX8YSqybA2xO4ggKY9ELpNswjQv0qc9jqS0Wqca/yxw9X8ITCgezDEGuHZCmfdrUgTnAMS3gEzma34exG9898vF4nOB+L8LP3cgBPKLx/iTFg36EX/oCtx/N3Bqe/+kkdKAOMFGlA+HUIlm6k0dCQ9ICPyvdN6EMpommudJFPwwVTihaHofkk1i7LDtrFJ6zIBRYBoIJqb2yq/6mV4a8rFNmIidhhHEQIi90S26cJUjIi1JC6dy5PGuVlmeeo6BWFikyFdeAxlp0Z3N4BMqAhgukqU2zuvJJxuUHpFqpQSTQfgiTP6PKDHgw8nBI/ke3j8OxhyBJebpeZIijOMXcjxBQK9LcHViqArYs3apGg23KHFlCEcRSUoolpaAxJf58kcLSgT1vgft/HePh0cB9c+I3huRmz4m6lc2maUrxYDDB/smIsrXuwHmUIKWonG6tfWYhXcosauavP1+6jZqKUGiSTyRQEnAUJ5gvloiEQEq8ZjKnfgLfDyCiCCF5lqYoimJVlEUcY0Qk+8xdpeHTxne2doAix963D7Dz8hVc3r6Kbz64hetfv4+Pb3+Ot17cxtuvvo4XLl3GZ9fexfd//lgDcvindNrfp2McT2YUtsGSyH9vexfJYoqvvriHa6+9gq2dXex9+Al2v7yJjz69gxsvXcXNN97EpStbuHP9BvYe3ltx2BC6eigqKKWgKfVSl4gTSpEo0JSWR+mnOemP5iW1WZa5viqUE0aHq7oknga0kFOe0sa5iM+Rz9WUVBC+WmkmScRrxWmeOVNXvMOF6FFBHveH8ILI6ZBvDVtRkt5IHjlHQxHEFJEfxTSuAfmboiyU5mLqGpA1dzie4IRuy5PBKY68KV0xfUEODM7ZLAgwjDMnLT6Mo+S2BeSBoJNDqiynHjInZdkCuR+3Zy82C5r1ud8dEW96xb+1qxc7yvJaMhtRrffX3UXWcHfGcwuoaZLT7VNRTDO5UXUuiqY7zWPmy1jTgjF4/fdhmpQtnpIG+YHgwrBz6uuAvDhR0o39NEZWqPZ7TDeHTeSZO8hdPZbKgkC4ylzhTKkLkW4+Ath4Zdp/PfyPXRQ7nstxY/8Bn9QtRQ0MYuMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Server-side event loop&quot;
        title=&quot;&quot;
        src=&quot;/static/server-event-loop-ab34e08e11d5318628f70921613bba89-fb8a0.png&quot;
        srcset=&quot;/static/server-event-loop-ab34e08e11d5318628f70921613bba89-1a291.png 148w,
/static/server-event-loop-ab34e08e11d5318628f70921613bba89-2bc4a.png 295w,
/static/server-event-loop-ab34e08e11d5318628f70921613bba89-fb8a0.png 590w,
/static/server-event-loop-ab34e08e11d5318628f70921613bba89-526de.png 885w,
/static/server-event-loop-ab34e08e11d5318628f70921613bba89-fa2eb.png 1180w,
/static/server-event-loop-ab34e08e11d5318628f70921613bba89-08f6a.png 1770w,
/static/server-event-loop-ab34e08e11d5318628f70921613bba89-53c32.png 5000w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Overall, we can’t say that database queries became &lt;em&gt;faster&lt;/em&gt; when you
look at a given request and response pair. But &lt;em&gt;throughput&lt;/em&gt; is much better
thanks to the introduction of an event loop (assuming your database is able to
handle the increase). For 6 requests by the end of diagram’s
timeline, 5 responses were issued, and it was done much earlier than it would have
happened in a blocking version. The CPU load is more evenly distributed within
one process, which reduces context switching overhead and server cost.&lt;/p&gt;
&lt;h3&gt;Current status of event loops on the server side&lt;/h3&gt;
&lt;p&gt;Nowadays, if you write server-side code, quite probably you already use an event
loop under the hood. Let’s have a quick overview of how major languages and
frameworks actually do this.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://nodejs.org/en/about/&quot;&gt;Node.js&lt;/a&gt; provides an implicit event loop in a
single thread that you work with. &lt;code&gt;setTimeout&lt;/code&gt;, &lt;code&gt;setImmediate&lt;/code&gt; and &lt;code&gt;setInterval&lt;/code&gt;
&lt;a href=&quot;https://nodejs.org/api/timers.html&quot;&gt;functions&lt;/a&gt; schedule closures to be executed
later by the default event loop. Turns out, &lt;a href=&quot;https://www.carlrippon.com/scalable-and-performant-asp-net-core-web-apis-asynchronous-operations/&quot;&gt;ASP.NET Core supports non-blocking
I/O&lt;/a&gt;
out of the box. This may not be so surprising, given that &lt;a href=&quot;https://en.wikipedia.org/wiki/C_Sharp_(programming_language)#Versions&quot;&gt;C# supported async
methods since
2012&lt;/a&gt;. If
you’re into &lt;a href=&quot;https://en.wikipedia.org/wiki/Java_virtual_machine&quot;&gt;JVM&lt;/a&gt; ecosystem,
&lt;a href=&quot;https://netty.io&quot;&gt;Netty&lt;/a&gt; is the way to go with event loops. And you probably
heard of it, &lt;a href=&quot;https://github.com/normanmaurer&quot;&gt;Norman Maurer&lt;/a&gt;, one of the main
contributors to Netty now works for Apple and is a top committer to the new
&lt;a href=&quot;https://github.com/apple/swift-nio&quot;&gt;SwiftNIO&lt;/a&gt; framework.&lt;/p&gt;
&lt;p&gt;Now we’ve mentioned Swift, &lt;a href=&quot;https://vapor.codes&quot;&gt;Vapor&lt;/a&gt; 3.0 already migrated
to SwiftNIO and there’s also a “tech preview of &lt;a href=&quot;https://github.com/IBM-Swift/Kitura/tree/kitura-nio&quot;&gt;Kitura on
SwiftNIO&lt;/a&gt;” available.
Interesting to note that SwiftNIO allows you to utilise &lt;a href=&quot;https://apple.github.io/swift-nio/docs/current/NIO/Classes/MultiThreadedEventLoopGroup.html&quot;&gt;event loops across
multiple
threads&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Scaling event loops across multiple threads is a very powerful concept and is
something that’s also already available on the language level in
&lt;a href=&quot;https://golang.org&quot;&gt;Go&lt;/a&gt; and &lt;a href=&quot;https://elixir-lang.org&quot;&gt;Elixir&lt;/a&gt;. While I have my
share of scepticism for both Go&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; and Elixir&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, these are very interesting
languages that I highly recommend to explore and wrap your head around.&lt;/p&gt;
&lt;p&gt;In our day and age of diminishing returns from &lt;a href=&quot;https://en.wikipedia.org/wiki/Moore%27s_law&quot;&gt;Moore’s
law&lt;/a&gt;, being able to easily scale
tasks across multiple CPU cores, GPUs and other devices is indispensable.
Concurrency, parallelism and distributed computing is the new functional
programming. 🤓 In some sense, these topics initially seem to be difficult and
obscure, but can drastically improve how you approach different problems when
you have at least some understanding of basic concepts.&lt;/p&gt;
&lt;h2&gt;How do you even deploy a backend app without an event loop?&lt;/h2&gt;
&lt;p&gt;For quite some time event loops weren’t as popular in backend software as they
are now. Back in the 90s, spawning a new process for every HTTP request seemed
normal, I refer you to the history of &lt;a href=&quot;https://en.wikipedia.org/wiki/Common_Gateway_Interface&quot;&gt;Common Gateway
Interface&lt;/a&gt; for more info
on this. A few optimisations followed, like
&lt;a href=&quot;https://en.wikipedia.org/wiki/Simple_Common_Gateway_Interface&quot;&gt;SCGI&lt;/a&gt; and
&lt;a href=&quot;https://en.wikipedia.org/wiki/FastCGI&quot;&gt;FastCGI&lt;/a&gt;, but they still maintained a
clear separation between an HTTP server and request handling itself. An HTTP
server (e.g. &lt;a href=&quot;https://httpd.apache.org&quot;&gt;Apache&lt;/a&gt;) could have used an event loop
on the lower level, but the application logic still lived in a separate process.
It was possible to eke out a bit more performance by spawning multiple worker
processes or threads, but this still caused context switching overhead and
same blocking I/O bottlenecks as previously.&lt;/p&gt;
&lt;p&gt;You could’ve asked: “who even writes blocking HTTP code these days?“. Well, if
you’re writing code for Python 3.2 and older, most probably you don’t have
access to &lt;a href=&quot;https://pypi.org/project/asyncio/&quot;&gt;asyncio&lt;/a&gt;, which is Python’s
standard implementation of event loops. Most popular Python’s web frameworks
like &lt;a href=&quot;http://flask.pocoo.org&quot;&gt;Flask&lt;/a&gt; and &lt;a href=&quot;https://www.djangoproject.com&quot;&gt;Django&lt;/a&gt;
are synchronous, not powered by an event loop and are commonly deployed via
&lt;a href=&quot;https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface&quot;&gt;WSGI&lt;/a&gt;. The most
popular HTTP client library
&lt;a href=&quot;https://requests.readthedocs.io/en/master/&quot;&gt;&lt;code&gt;requests&lt;/code&gt;&lt;/a&gt; provides only blocking
API as well.&lt;sup id=&quot;fnref-3&quot;&gt;&lt;a href=&quot;#fn-3&quot; class=&quot;footnote-ref&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; When you do have access to newer Python versions and to
&lt;a href=&quot;https://docs.python.org/3/library/asyncio.html&quot;&gt;asyncio&lt;/a&gt;, event loops there are
a bit more explicit than in Node.js, but the underlying concept is still the
same.&lt;/p&gt;
&lt;p&gt;While I don’t have much exposure to Ruby and &lt;a href=&quot;https://rubyonrails.org&quot;&gt;Ruby on
Rails&lt;/a&gt;, in my research I haven’t found any event loop frameworks that
have become mainstream. It does look like most common solutions for deployment
&lt;a href=&quot;http://blog.scoutapp.com/articles/2017/02/10/which-ruby-app-server-is-right-for-you&quot;&gt;utilise multithreading and
multiprocessing&lt;/a&gt;
to improve scalability.&lt;/p&gt;
&lt;p&gt;Similarly with PHP, while &lt;a href=&quot;https://github.com/reactphp/react&quot;&gt;ReactPHP&lt;/a&gt; is about
5 years old at this point, you can’t beat inertia of deploying &lt;a href=&quot;https://codex.wordpress.org/Installing_WordPress&quot;&gt;WordPress on
Apache&lt;/a&gt;. 😄&lt;/p&gt;
&lt;h2&gt;How do event loops work?&lt;/h2&gt;
&lt;p&gt;There is a ton of details hidden under the hood that we don’t need to worry
about on a daily basis. After all, event loops are meant to improve how we work
with I/O-bound tasks and most of I/O stuff can get complicated real quick.&lt;/p&gt;
&lt;p&gt;A good explanation is this pseudocode from &lt;a href=&quot;https://github.com/apple/swift-nio/blob/2fec7a97662e0a12f834dee08d14c659c8aacd22/Sources/NIO/EventLoop.swift#L170&quot;&gt;SwiftNIO
documentation&lt;/a&gt;.
As SwiftNIO is primarily a server-side framework, a channel here means a server
connection established by a client. But on a low level, this is applicable to UI
event loops too. From a certain perspective, interactions with touch sensors,
display drivers and GPUs can be considered I/O.&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;while&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;eventLoop&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.isOpen&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Block until there is something to process for 1...n Channels&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;readyChannels&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;blockUntilIoOrTasksAreReady&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Loop through all the Channels&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;for&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;channel&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;readyChannels&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// Process IO and / or tasks for the Channel.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// This may include things like:&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;///    - accept new connection&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;///    - connect to a remote host&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;///    - read from socket&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;///    - write to socket&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;///    - tasks that were submitted via EventLoop methods&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;/// and others.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;processIoAndTasks&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;Here &lt;code&gt;blockUntilIoOrTasksAreReady&lt;/code&gt; interacts with sockets or
device drivers via system calls and provides events that are ready to process.
In turn, &lt;code&gt;processIoAndTasks&lt;/code&gt; dispatches those events to corresponding callbacks
that were registered on previous event loop iterations.&lt;/p&gt;
&lt;h2&gt;Disadvantages of event loops&lt;/h2&gt;
&lt;p&gt;As I previously mentioned, the &lt;a href=&quot;#server-event-loop-diagram&quot;&gt;server-side event loop
diagram&lt;/a&gt; is a bit harder to read when establishing
the sequence of events. This especially might get in the way during debugging.
In a function call stacktrace you probably would be able to see what kind of
event led to a specific callback handler, but tracing it to the original
code that scheduled the handler has to be done separately.&lt;/p&gt;
&lt;p&gt;You might’ve stumbled upon a similar problem when debugging multithreaded code.
A stacktrace of a particular thread can be retrieved, but by the time your
point of interest executes, the original thread that scheduled the work has
already moved on to completely different code.&lt;/p&gt;
&lt;p&gt;In a situation with multiple threads, this can be further complicated by the use of
synchronisation primitives and non-deterministic nature of thread scheduling. On
the contrary, if your event loop code is single-threaded and tasks are scheduled
and handled from the same thread, it’s not as bad.&lt;/p&gt;
&lt;p&gt;A quite acceptable solution is to maintain a separate callback stack trace that
can be examined later when needed. For example, SwiftNIO records &lt;a href=&quot;https://github.com/apple/swift-nio/blob/530f8eac1e0cc942252e670fec140892229a398d/Sources/NIO/EventLoopFuture.swift#L161&quot;&gt;file names and
line numbers of futures and promises&lt;/a&gt;
that were created. This information is then logged if a deallocated future was
unfulfilled, indicating that there is a potential leak creating redundant future
objects. In principle, a higher level framework (say an HTTP server) could
attach richer information to its own stack of requests to be logged when something
goes wrong.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;It would be fair to say that an event loop is a great tool for building
high-performance and scalable applications. We’ve looked into how it helps with both
UI and server-side code. Specifically, on the server side, there are plenty of
approaches, different languages and frameworks evolved in different ways that
are still fundamentally the same under the hood.&lt;/p&gt;
&lt;p&gt;Non-blocking I/O on a low level can be relatively tricky, and it’s great that
event loops can abstract this away. There are a few caveats with regards to
debugging event loop based code, but it’s something that can be overcome with
tooling, better support from frameworks and runtime of a programming language
that you use.&lt;/p&gt;
&lt;p&gt;As with any tool, it’s important to know the use cases and apply it where it
fits best. With event loops, you can get substantial gains in throughput and
responsiveness of your apps if applied well, while paying a small cost of
recording more runtime information to ease debugging if needed.&lt;/p&gt;
&lt;p&gt;I hope I provided some information on that in the article, but please feel free
to shoot a message on &lt;a href=&quot;https://twitter.com/maxdesiatov&quot;&gt;Twitter&lt;/a&gt; or
&lt;a href=&quot;https://mastodon.social/@maxd&quot;&gt;Mastodon&lt;/a&gt; with your comments and questions. Talk
soon. 👋&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;  No generics in a statically typed language in 2018? &lt;a href=&quot;https://blog.golang.org/error-handling-and-go&quot;&gt;Boilerplate error
handling&lt;/a&gt;? Some say this all
happened on purpose to keep things simple and minimalistic. Sorry, this
doesn’t feel to me like minimalism, more like
&lt;a href=&quot;https://en.wikipedia.org/wiki/Brutalism&quot;&gt;brutalism&lt;/a&gt;. 😄&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;  While Elixir is a great improvement on top of &lt;a href=&quot;http://www.erlang.org&quot;&gt;Erlang&lt;/a&gt;,
limitations of dynamic virtual machines become too obvious when trying to
write CPU-bound code. Calling into native binaries &lt;a href=&quot;http://erlang.org/doc/tutorial/nif.html&quot;&gt;is quite difficult&lt;/a&gt;, but
I love how Elixir makes distributed computing &lt;a href=&quot;https://elixir-lang.org/getting-started/mix-otp/distributed-tasks-and-configuration.html&quot;&gt;native to the language and its
standard library&lt;/a&gt;.&lt;/p&gt;
&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;  The situation with Python and blocking APIs is peculiar enough to be considered
in more detail. I’m convinced that this is a great illustration of how
important ergonomics of programming languages is. It was possible for
a long time to build asynchronous non-blocking applications in JavaScript,
especially with Node.js. New language features such as generators and
&lt;code&gt;async/await&lt;/code&gt; have given JavaScript mostly syntax sugar to help with patterns
that have been available for a while. Compare this with Python, where even
in 2018 with the availability of &lt;code&gt;async/await&lt;/code&gt; and new libraries based on event
loops, a lot of people still hesitate to make a transition to non-blocking I/O.&lt;/p&gt;
&lt;p&gt;  Admittedly, Python 2 to Python 3 migration could explain some of this
conservatism, but it doesn’t explain the scarcity of callback-based APIs in
Python 2. What is important to consider is a lack of a crucial,
but frequently overlooked language feature: anonymous closures/lambdas with
multiple statements. Lambdas in Python allow only a single expression within,
and this prevents you from creating an ergonomic callback-based non-blocking
API. While libraries such as &lt;a href=&quot;https://twistedmatrix.com/trac/&quot;&gt;Twisted&lt;/a&gt;
existed at the time, their API based on delegates wasn’t very accessible.&lt;/p&gt;
&lt;p&gt;  In turn, delegates are pretty good when you’re able to express a required
delegate shape with protocols/interfaces. Python lacks those too, although
something similar can be hacked with &lt;a href=&quot;https://docs.python.org/3/library/abc.html&quot;&gt;abstract base
classes&lt;/a&gt;.&lt;/p&gt;
&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[How do closures and callbacks work? It's turtles all the way down]]></title><description><![CDATA[This article is a part of my series about concurrency and asynchronous
programming in Swift. The articles are independent, but after reading…]]></description><link>https://desiatov.com/closures/</link><guid isPermaLink="false">https://desiatov.com/closures/</guid><pubDate>Tue, 26 Jun 2018 12:40:32 GMT</pubDate><content:encoded>&lt;p&gt;This article is a part of my series about concurrency and asynchronous
programming in Swift. The articles are independent, but after reading this one
you might want to check out the rest of the series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;How do closures and callbacks work? It’s turtles all the way
down&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;&lt;a href=&quot;/event-loops#title&quot;&gt;Event loops, building smooth UIs, and handling high server load&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;&lt;a href=&quot;/swift-structured-concurrency-introduction#title&quot;&gt;Introduction to structured concurrency in Swift: continuations, tasks, and
cancellation&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;blockquote&gt;
&lt;p&gt;The saying holds that the world is supported by a chain of increasingly large
turtles. Beneath each turtle is yet another: it is “turtles all the way down”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Turtles_all_the_way_down&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/River_terrapin-addd7cb120ca514a7afca36d3a078f8c-d45ff.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block; ; max-width: 350px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 126.28571428571429%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAZABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAMCBAUB/8QAFwEBAQEBAAAAAAAAAAAAAAAAAgMAAf/aAAwDAQACEAMQAAABt8RRmtkQT5HO16rzSQD/AP/EABwQAAICAgMAAAAAAAAAAAAAAAECAAMREgQhMf/aAAgBAQABBQLGIzamWmElZUdq3Gy2J3SpVJyPTP/EABURAQEAAAAAAAAAAAAAAAAAABAB/9oACAEDAQE/ASn/xAAXEQADAQAAAAAAAAAAAAAAAAAAAREQ/9oACAECAQE/AZlGf//EABsQAAICAwEAAAAAAAAAAAAAAAABEBEhMYFB/9oACAEBAAY/AtmZ96JsxsVFM4KP/8QAHhAAAgMAAQUAAAAAAAAAAAAAAAERIUFxMYGh4fD/2gAIAQEAAT8hVCk28IVRgv5EPYiHLJ2pGkC49g2g046MR03yYPEZjg//2gAMAwEAAgADAAAAEHv+jf/EABgRAAIDAAAAAAAAAAAAAAAAAAABEBEh/9oACAEDAQE/EHkMWf/EABcRAQEBAQAAAAAAAAAAAAAAAAEAESH/2gAIAQIBAT8QNzxtku3/xAAgEAEAAgEEAgMAAAAAAAAAAAABABEhMVFhwUFxkbHw/9oACAEBAAE/EEb4oKjO8WzU0I0mIrdL+UW6moNNLgDAuSPPBDbXWm76mM2mAuzdpAihAg0OwvUUzdVAlcTx9Op+pvPrT//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Turtles. All. The. Way. Down.&quot;
        title=&quot;&quot;
        src=&quot;/static/River_terrapin-addd7cb120ca514a7afca36d3a078f8c-d45ff.jpg&quot;
        srcset=&quot;/static/River_terrapin-addd7cb120ca514a7afca36d3a078f8c-b16f2.jpg 148w,
/static/River_terrapin-addd7cb120ca514a7afca36d3a078f8c-dc3a7.jpg 295w,
/static/River_terrapin-addd7cb120ca514a7afca36d3a078f8c-d45ff.jpg 350w&quot;
        sizes=&quot;(max-width: 350px) 100vw, 350px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;center&gt;&lt;small&gt;By Pelf at &lt;a href=&quot;https://commons.wikimedia.org/wiki/File:River_terrapin.jpg&quot;&gt;en.wikipedia&lt;/a&gt;,
public domain, via Wikimedia Commons&lt;/small&gt;&lt;/center&gt;&lt;br/&gt;
&lt;p&gt;In a few episodes of great podcast &lt;a href=&quot;https://www.relay.fm/analogue&quot;&gt;Analog(ue)&lt;/a&gt;
hosts Casey and Myke discuss &lt;a href=&quot;https://youtu.be/gI-qXk7XojA&quot;&gt;Crash Course Computer
Science&lt;/a&gt; series and how it presents abstractions.
In software engineering and computer science, we constantly deal with layers of
abstractions, but we don’t cross too many of them on daily basis. We work with
software libraries that are built on top of a few modules and functions, which
are written in a programming language, which is executed as binary code, which
runs on CPUs and GPUs, which use logic gates built with transistors, to
understand which you might need to understand chemistry and physics. Quite
possibly someday particle physicists will discover a few more turtles further
down the stack. But as long as you use that software library, you don’t need to
care about logic gates, transistors and quantum tunnelling.&lt;/p&gt;
&lt;p&gt;So here’s an abstraction that developers work with a lot: asynchronous
computations. These days it’s hard to write code that doesn’t touch something
asynchronous: any kind of I/O, most frequently networking, or maybe long-running
tasks that are scheduled on different threads/processes. For something more
concrete, consider a database query, which could be local disk I/O or something
that sits somewhere on the network.&lt;/p&gt;
&lt;p&gt;I want to write better code and build more abstractions where needed and where
it makes the most sense. Because of that, I’ve recently spent a lot of time
researching and trying to understand different ways to deal with asynchronous
code. In a lot of programming languages callbacks is one of the ways to write
it, but it’s also a relatively low level to deal with this abstraction.
Nevertheless, it’s important to understand how it works on this level and what
can be built on top of it. I hope my explanation could be useful to you as well.&lt;/p&gt;
&lt;h2&gt;Using closures&lt;/h2&gt;
&lt;p&gt;In Swift using callbacks is the main way to deal with asynchronicity. While
Swift is taken as an example, I don’t use or discusss any advanced features here
and I hope it’s going to be interesting even if you don’t use Swift on daily
basis.&lt;/p&gt;
&lt;p&gt;To pass a callback you could use a “closure”. &lt;a href=&quot;https://docs.swift.org/swift-book/LanguageGuide/Closures.html&quot;&gt;The Swift Programming Language
Guide&lt;/a&gt; introduces
it this way:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.&lt;/p&gt;
&lt;p&gt;Closures can capture and store references to any constants and variables from the context in which they are defined. This is known as closing over those constants and variables.&lt;/p&gt;
&lt;p&gt;[…]&lt;/p&gt;
&lt;p&gt;Global and nested functions, as introduced in &lt;a href=&quot;https://docs.swift.org/swift-book/LanguageGuide/Functions.html&quot;&gt;Functions&lt;/a&gt;, are actually special cases of closures. Closures take one of three forms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Global functions are closures that have a name and do not capture any values.&lt;/li&gt;
&lt;li&gt;Nested functions are closures that have a name and can capture values from their enclosing function.&lt;/li&gt;
&lt;li&gt;Closure expressions are unnamed closures written in a lightweight syntax that can capture values from their surrounding context.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;small&gt;Copyright © 2018 Apple Inc. Excerpt provided for personal use.&lt;/small&gt;
&lt;br/&gt;&lt;br/&gt;
Here’s a simple example of a closure that returns a sum of captured variable and its own argument.&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;a&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;10&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Int&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;x&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;+&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;a&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// x = 5, a = 10, returns 15&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;a&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;15&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// x = 5&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// a in captured environment is 15&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// f returns 20&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;g&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// assigned closure f to a new constant g&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// x = 5&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// g now references same environment,&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// where a is set to 15&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// g returns 20&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;a&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;20&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// a in captured environment is 20&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// f returns 25&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// g shares environment with f,&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// where a is set to 20&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// g returns 25&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;At this point, we can say that a closure is just function code with some
captured environment. “Environment” means variables and constants defined
outside of closure body. “Capturing” means you have access to a variable value
in the environment. If that variable was subsequently modified before closure
execution, code within the closure would get the latest up-to-date value.
Obviously, constant values are captured as well, but by definition, they can’t
be changed.&lt;/p&gt;
&lt;p&gt;The example code is wrapped in a function to demonstrate that environment can be
local to a current scope as opposed to global environment. If variable &lt;code&gt;a&lt;/code&gt; was
declared globally, there wouldn’t be anything interesting in using its value,
but capturing access to it in local scope requires special treatment in the
language implementation.&lt;/p&gt;
&lt;p&gt;As seen in the example above, closures have reference semantics, not value
semantics. Assigning a closure to a variable doesn’t create a copy of that
closure and its environment, but only creates a reference to that. If you were
to pass a closure as an argument, it would be passed &lt;a href=&quot;https://en.wikipedia.org/wiki/Evaluation_strategy&quot;&gt;by reference, not by
value&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A more interesting example of closure and callback use:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;backend&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Backend&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;indicator&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;UIActivityIndicatorView&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;label&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;UILabel&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// non-blocking code&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;backend&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.login&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;onCompletion&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;failure&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// code called when `backend.login` completes.&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// indicator variable captured here&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;indicator&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.stopAnimating&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// UILabel instance is captured here&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.text&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;\(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;success&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;??&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;)&quot;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;})&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// some other code here that&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// won&apos;t be blocked by `backend.login`&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// e.g. UI updates&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;indicator&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.startAnimating&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;h2&gt;How would you implement closures on a lower level?&lt;/h2&gt;
&lt;p&gt;Because explaining closures in terms of closures doesn’t make much sense, let’s
imagine a programming language that doesn’t have them. To tell a story about the
closure turtle, we need to place it on top of other turtles.&lt;/p&gt;
&lt;p&gt;What follows is an example of how this &lt;em&gt;could&lt;/em&gt; work. It doesn’t require any
knowledge of how compilers work, it’s just a lower level representation of
closures for our studies.&lt;/p&gt;
&lt;p&gt;Consider a subset of Swift, where functions (including anonymous functions) can’t
capture the outside environment. That is a language where this:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;a&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Int&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;x&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;+&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;a&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;g&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;x&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;x&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;+&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;a&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;would cause two compiler errors about &lt;code&gt;a&lt;/code&gt; being undefined in the body of functions &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To implement closures in this imaginary language, we’d need to use classes to
get the reference semantic mentioned above. It’s also useful to have a protocol
defining a generic closure shape. It could look like this:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;protocol&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Closure&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;associatedtype&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Environment&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;associatedtype&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Input&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;associatedtype&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Output&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Environment&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;get&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;set&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;willRun&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Output&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;And here’s a class conforming to this protocol and implementing our closure with
example usage code:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Closure&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Environment&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Int&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.a&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;a&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Environment&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Environment&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.e&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;e&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;willRun&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;_&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable-2&quot;&gt;Int&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;x&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;+&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.a&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;var&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;e&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.Environment&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;f&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.willRun&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// returns 15&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.a&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;15&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.willRun&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// returns 20&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;g&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.willRun&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// returns 20&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.a&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;20&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.willRun&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// returns 25&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.willRun&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// returns 25&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;&lt;a name=&quot;delegate-objects&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Well, this is verbose. But it’s a pattern you might consider when writing in C,
C++ before C++11 and its support for lambdas, or Objective-C before blocks were
introduced. And here’s a point that I often don’t see mentioned when closures
are explained: you can think of closures as syntactic sugar for anonymous
&lt;a href=&quot;https://en.wikipedia.org/wiki/Delegation_pattern&quot;&gt;delegates&lt;/a&gt;. If you have
experience with Objective-C or Cocoa, you might have noticed &lt;a href=&quot;https://stackoverflow.com/questions/626898/how-do-i-create-delegates-in-objective-c&quot;&gt;the
analogy&lt;/a&gt;
already, I deliberately named the protocol function &lt;code&gt;willRun&lt;/code&gt; similarly to Cocoa
delegate function naming pattern.&lt;/p&gt;
&lt;p&gt;Under the hood, a closure-capable compiler will generate a separate function
body with a corresponding environment when it sees there are actual variable
captures going on. In some implementations, like C++11, you have to specify a
list of captured variables explicitly. In Objective-C, that’s what the &lt;code&gt;__block&lt;/code&gt;
modifier is for, while in Swift it’s automatic by default with a possibility to
override it. The latter is quite handy when you want some variables to be
captured with weak references to avoid reference cycles.&lt;/p&gt;
&lt;h2&gt;Callbacks and asynchronous code&lt;/h2&gt;
&lt;p&gt;In a lot of cases using the right abstractions saves us from verbosity in our code.
Are callbacks a good abstraction for all asynchronous scenarios then?&lt;/p&gt;
&lt;p&gt;Consider a more complex version of the code we’ve seen before:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;label&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;UILabel&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// non-blocking code&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;backend&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.login&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;onCompletion&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;failure&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// called when `backend.login` completes.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// UILabel instance is captured here&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.text&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;success&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;guard&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;failure&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;else&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// error handling here&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// notice `backend` is captured here as well&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;backend&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.fetchUserInfo&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;userInfo&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;failure&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;guard&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;failure&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;else&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// error handling here again&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;if&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;userInfo&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.isAdmin&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;backend&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.doAdminStuff&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;failure&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;guard&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;failure&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// tired of repeated manual&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// error handling by this point...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// more code here to&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;        &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// handle admin stuff results&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;})&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// some other code here that&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// won&apos;t be blocked by `backend.login`&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;To handle a sequence of async actions we need to use nested callbacks. Turns out
it’s quite easy to start building these pyramids of doom. Error handling is
quite tedious and overall this type of code becomes quite error-prone with
shadowed variables all around: notice shadowed &lt;code&gt;failure&lt;/code&gt; callback argument
within all completion handlers. With plain callbacks, this isn’t an exaggerated
scenario, you can often stumble upon this when building real apps that involve
any kind of long-running non-blocking operation, e.g. networking.&lt;/p&gt;
&lt;h2&gt;Promises of future turtles&lt;/h2&gt;
&lt;p&gt;There is a way out, consider a concept called “futures”, also know as
“promises”. Using &lt;a href=&quot;https://github.com/ThomVis/BrightFutures&quot;&gt;BrightFutures&lt;/a&gt;
library as an example, the pyramid of doom can be converted to this flat chain
of futures:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;let&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;label&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;UILabel&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// non-blocking code&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;backend&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.login&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;,&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.flatMap&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;success&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// called when `backend.login` succeeds.&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// UILabel instance is captured here&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.text&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;=&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;success&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;backend&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.fetchUserInfo&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.onSuccess&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;userInfo&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;in&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;if&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;userInfo&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.isAdmin&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;backend&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.doAdminStuff&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;()&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.onSuccess&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// more code here to handle&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// admin stuff results&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;.onFailure&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;guard&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;failure&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;else&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// unified error handling here,&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// that can be triggered by any&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// future in the chain&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;return&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// ...&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// some other code here that&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-comment&quot;&gt;// won&apos;t be blocked by `backend.login`&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;That’s much better, we have only one error handler that will be triggered
regardless of where an error might occur. There is only one nested callback
after &lt;code&gt;backend.fetchUserInfo()&lt;/code&gt; and only because we have other async code
executed on a condition that our user is an admin. More readability and much
easier to maintain and refactor if you need to re-order the async operations.&lt;/p&gt;
&lt;p&gt;This code assumes you’ve converted all callback-based functions like &lt;code&gt;login&lt;/code&gt;,
&lt;code&gt;fetchUserInfo&lt;/code&gt; and &lt;code&gt;doAdminStuff&lt;/code&gt; to return futures. What’s a future? Think of
it as a container that can only be opened at some later time (in the future) and
it might contain either an actual result or an error. You can attach callbacks
to a future “container” to be triggered when the computation is ready, and you
can chain these containers together to run a sequence (or sometimes a parallel
batch) of asynchronous computations. A simplified declaration could look like
this:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;onSuccess&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;())&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;onFailure&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;())&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;NewResult&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;transformer&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;NewResult&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;NewResult&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;func&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-def&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;NewResult&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;transformer&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;NewResult&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span &gt;    &lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;-&gt;&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;cm-variable&quot;&gt;NewResult&lt;/span&gt;&lt;span class=&quot;cm-operator&quot;&gt;&gt;&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;There’s a peculiar &lt;code&gt;flatMap&lt;/code&gt; function here. In a few other Swift libraries
implementing futures, it’s called &lt;code&gt;then&lt;/code&gt;, which is a more straightforward name
if you don’t focus on the container aspect of futures. In the JavaScript
standard library the &lt;code&gt;Promise&lt;/code&gt; class uses the name
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then&quot;&gt;&lt;code&gt;then&lt;/code&gt;&lt;/a&gt;
as well.&lt;/p&gt;
&lt;p&gt;So why name it &lt;code&gt;flatMap&lt;/code&gt;? Turns out there is already a
&lt;a href=&quot;https://developer.apple.com/documentation/swift/sequence/2905332-flatmap&quot;&gt;&lt;code&gt;flatMap&lt;/code&gt;&lt;/a&gt;
function in Swift standard library defined on the
&lt;a href=&quot;https://developer.apple.com/documentation/swift/sequence&quot;&gt;&lt;code&gt;Sequence&lt;/code&gt;&lt;/a&gt; protocol,
which is similar to
&lt;a href=&quot;https://developer.apple.com/documentation/swift/sequence/2965520-map&quot;&gt;&lt;code&gt;map&lt;/code&gt;&lt;/a&gt;
you’ve probably used if you’re into functional programming. Standard &lt;code&gt;map&lt;/code&gt;
transforms a container of elements of type &lt;code&gt;A&lt;/code&gt; to a container of elements of
type &lt;code&gt;B&lt;/code&gt; with a closure of type &lt;code&gt;(A) -&gt; B&lt;/code&gt;. &lt;code&gt;flatMap&lt;/code&gt; does the same for closures
of type &lt;code&gt;(A) -&gt; [B]&lt;/code&gt;, if we assume this container is an array. With simple &lt;code&gt;map&lt;/code&gt;
the end result would be of type &lt;code&gt;[[B]]&lt;/code&gt;, which is a container of containers.
This isn’t something you’d always want, so to “flatten” these containers to only
one level &lt;code&gt;[B]&lt;/code&gt; use &lt;code&gt;flatMap&lt;/code&gt;. It works the same way for all types of containers
that implement the &lt;code&gt;Sequence&lt;/code&gt; protocol.&lt;/p&gt;
&lt;p&gt;To chain &lt;code&gt;Future&amp;#x3C;A&gt;&lt;/code&gt; with &lt;code&gt;Future&amp;#x3C;B&gt;&lt;/code&gt; that depends on result &lt;code&gt;A&lt;/code&gt;, our result
transformer closure would need to look like &lt;code&gt;A -&gt; Future&amp;#x3C;B&gt;&lt;/code&gt;. Taking this
analogy further, if you applied this closure to simple &lt;code&gt;map&lt;/code&gt;, you’d get the end
result of type &lt;code&gt;Future&amp;#x3C;Future&amp;#x3C;B&gt;&gt;&lt;/code&gt;, which is bananas and doesn’t make any sense.
Hence we use &lt;code&gt;flatMap&lt;/code&gt; to get a “flat” result type.&lt;/p&gt;
&lt;h2&gt;More turtles coming…&lt;/h2&gt;
&lt;p&gt;We’ve just reviewed closures and had a quick look at how they’re used for
callbacks. We tried to write asynchronous code with callbacks and found that
it’s not very maintanable. In the end we tried using futures, which leveraged
closures as well, but allowed us to structure the example code in a better way.&lt;/p&gt;
&lt;p&gt;Admittedly, this futures stuff is an ok abstraction, but it doesn’t feel as smooth
writing plain old synchronous code. If only we could write non-blocking
asynchronous code that almost looked like usual synchronous code… Turns out,
plenty of programming languages provide a few abstractions to work with
asynchronous code and concurrency, like coroutines and
&lt;a href=&quot;https://en.wikipedia.org/wiki/Await&quot;&gt;&lt;code&gt;async/await&lt;/code&gt;&lt;/a&gt; syntax sugar in JavaScript,
Python, C# to name a few. Some take a different approach, e.g. Erlang/Elixir and
Pony are built on &lt;a href=&quot;https://en.wikipedia.org/wiki/Actor_model&quot;&gt;actor model&lt;/a&gt;,
while Go introduces &lt;a href=&quot;https://en.wikipedia.org/wiki/Go_(programming_language)#Concurrency&quot;&gt;goroutines and
channels&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;Special thanks to &lt;a href=&quot;http://kimmett.me&quot;&gt;Neil Kimmett&lt;/a&gt; for feedback on draft versions
of this article. Thanks to &lt;a href=&quot;https://www.thomasvisser.me&quot;&gt;Thomas Visser&lt;/a&gt; for
&lt;a href=&quot;https://github.com/Thomvis/BrightFutures&quot;&gt;BrightFutures&lt;/a&gt; library, which is still
the best helper for writing async code in Swift in my opinion.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why I use GraphQL and avoid REST APIs]]></title><description><![CDATA[Server interactions take a significant amount of
time and effort to develop and test in most mobile and web apps.
In apps with most complex…]]></description><link>https://desiatov.com/why-graphql/</link><guid isPermaLink="false">https://desiatov.com/why-graphql/</guid><pubDate>Mon, 28 May 2018 12:40:32 GMT</pubDate><content:encoded>&lt;p&gt;Server interactions take a significant amount of
time and effort to develop and test in most mobile and web apps.
In apps with most complex APIs I worked on, the networking layer took up to
40% of the development time to design and maintain, specifically due to some
of the edge cases I mention below in this article.
After
implementing this a few times, it’s easy
to see different patterns, tools and frameworks that can help with this. While we’re
lucky (well, most of us are, I hope) not to care about
&lt;a href=&quot;https://en.wikipedia.org/wiki/SOAP&quot;&gt;SOAP&lt;/a&gt; anymore, &lt;a href=&quot;https://en.wikipedia.org/wiki/Representational_state_transfer&quot;&gt;REST&lt;/a&gt; isn’t the end of history
either.&lt;/p&gt;
&lt;p&gt;Recently I had a chance to develop and to run in production a few mobile and
web apps built with &lt;a href=&quot;http://graphql.org&quot;&gt;GraphQL&lt;/a&gt; APIs, both for my own projects and my clients.
This has been a
really good experience, not least thanks to wonderful &lt;a href=&quot;https://www.graphile.org/postgraphile/&quot;&gt;PostGraphile&lt;/a&gt; and &lt;a href=&quot;https://www.apollographql.com/client&quot;&gt;Apollo&lt;/a&gt;
libraries. At this point, it’s quite hard for me to come back and
enjoy working with REST.&lt;/p&gt;
&lt;p&gt;But obviously, this needs a little explanation.&lt;/p&gt;
&lt;h2&gt;So what’s wrong with REST?&lt;/h2&gt;
&lt;h3&gt;Every REST API is a snowflake&lt;/h3&gt;
&lt;p&gt;To be fair, REST isn’t even a standard. Wikipedia
&lt;a href=&quot;https://en.wikipedia.org/wiki/Representational_state_transfer&quot;&gt;defines&lt;/a&gt;
it as&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;an architectural style that defines a set of constraints and properties based on HTTP&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While something like &lt;a href=&quot;http://jsonapi.org&quot;&gt;JSON API&lt;/a&gt; spec does exist, in practice
it’s very rare that you see a RESTful backend implementing it.
In best case scenario, you might stumble upon something that uses
&lt;a href=&quot;https://en.wikipedia.org/wiki/OpenAPI_Specification&quot;&gt;OpenAPI/Swagger&lt;/a&gt;.
Even then, OpenAPI doesn’t specify anything about APIs shape or form, it’s
just a machine-readable spec, that allows (but not requires) you to run automatic
tests on your API, automatically generate documentation etc.&lt;/p&gt;
&lt;p&gt;The main problem is still there. You may say your API is RESTful, but there are
no strict rules in general on how endpoints are arranged or whether you should,
for example, use &lt;code&gt;PATCH&lt;/code&gt; HTTP method for object updates.&lt;/p&gt;
&lt;p&gt;There are also things that look RESTful on a first glance, but not
so much if you squint: &lt;a href=&quot;https://www.dropbox.com/developers/documentation/http/documentation&quot;&gt;Dropbox HTTP API&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;endpoints accept file content in the request body, so their arguments are instead passed as JSON in the &lt;code&gt;Dropbox-API-Arg&lt;/code&gt; request header or arg URL parameter.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;JSON in a request header? (╯°□°）╯︵ ┻━┻&lt;/p&gt;
&lt;p&gt;That’s right, there are Dropbox API endpoints that require you to leave request
body empty and to serialise a payload as JSON and chuck it an a custom HTTP
header. It’s fun to write client code for special cases like this. But
we can’t complain, because there is no widely-used standard after all.&lt;/p&gt;
&lt;p&gt;In fact, most of the caveats mentioned below are caused by lack of a standard,
but I’d like to highlight what I’ve seen in practice most frequently.&lt;/p&gt;
&lt;p&gt;And yes, you can avoid most of these problems in a disciplined experienced team,
but wouldn’t you want some of this stuff to be resolved already on a software
side?&lt;/p&gt;
&lt;h3&gt;No static typing means caring about type validation&lt;/h3&gt;
&lt;p&gt;No matter how much you try to avoid this, sooner or later you stumble upon
misspelt JSON properties, wrong data types sent or received, fields missing
etc. You’re probably ok if your client and/or server programming language is statically
typed and you just can’t construct an object with a wrong field name or type.
You’re probably doing good if your API is versioned and you have an old version on
&lt;code&gt;/api/v1&lt;/code&gt; URL and a new version with a renamed field on
&lt;code&gt;/api/v2&lt;/code&gt; URL. Even better if you have an OpenAPI spec that generates
client/server type declarations for you.&lt;/p&gt;
&lt;p&gt;But can you really afford all this in
all your projects? Can you afford setting up &lt;code&gt;/api/v1.99&lt;/code&gt; endpoint when during
a sprint your team decides to rename or rearrange object fields? Even if it’s done,
will the team not forget to update the spec and to ping the
client devs about the update?&lt;/p&gt;
&lt;p&gt;You sure you have all the validation logic right either on client or
on server? Ideally, you want it validated on both sides, right? Maintaining all
of this custom code is a lot of fun. Or keeping your API
&lt;a href=&quot;http://json-schema.org&quot;&gt;JSON Schema&lt;/a&gt; up to date.&lt;/p&gt;
&lt;h3&gt;Pagination and filtering is not so simple&lt;/h3&gt;
&lt;p&gt;Most APIs work with collections of objects. In a todo-list app, the list itself
is a collection. Most collections can contain more than 100 items. For most
servers returning all items in a collection in same response is a heavy operation.
Multiply that by a number of online users and it can add up to a hefty AWS bill.
Obvious solution: return only a subset of a collection.&lt;/p&gt;
&lt;p&gt;Pagination is comparatively straightforward. Pass something like &lt;code&gt;offset&lt;/code&gt; and
&lt;code&gt;limit&lt;/code&gt; values in query parameters: &lt;code&gt;/todos?limit=10&amp;#x26;offset=20&lt;/code&gt; to get only
10 objects starting at the 20th.
Everyone names these parameters differently, some prefer &lt;code&gt;count&lt;/code&gt; and &lt;code&gt;skip&lt;/code&gt;, I like &lt;code&gt;offset&lt;/code&gt;
and &lt;code&gt;limit&lt;/code&gt; because they directly correspond to SQL modifiers.&lt;/p&gt;
&lt;p&gt;Some backend databases expose cursors or tokens to be
passed for next page query. Check out
&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html&quot;&gt;Elasticsearch API&lt;/a&gt;
that recommends using &lt;code&gt;scroll&lt;/code&gt; calls when you need to go through a huge list of
resulting documents sequentially. There are also APIs that pass relevant information in headers. See &lt;a href=&quot;https://developer.github.com/v3/guides/traversing-with-pagination/&quot;&gt;GitHub REST API&lt;/a&gt;
(at least that’s not JSON passed in headers 😅).&lt;/p&gt;
&lt;p&gt;When it comes to filtering, it’s so much more interesting… Need filtering by
one field? No problem, it could be &lt;code&gt;/todos?filter=key%3Dvalue&lt;/code&gt; or maybe more
human-readable &lt;code&gt;/todos?filterKey=key&amp;#x26;filterValue=value&lt;/code&gt;. How’s about filtering
by two values? Hm, that should be easy, right? Query would look like
&lt;code&gt;/todos?filterKeys=key1%2Ckey2&amp;#x26;filterValue=value&lt;/code&gt; with &lt;a href=&quot;https://en.wikipedia.org/wiki/Percent-encoding&quot;&gt;URL encoding&lt;/a&gt;. But often there is no way
to stop the feature creep, maybe a requirement appears for advanced filtering
with &lt;code&gt;AND&lt;/code&gt;/&lt;code&gt;OR&lt;/code&gt; operators.
Or maybe complex full-text search queries together with complex filtering.
Sooner or later you can see a few APIs that invent their own filtering
&lt;a href=&quot;https://en.wikipedia.org/wiki/Domain-specific_language&quot;&gt;DSL&lt;/a&gt;. URL query
components are no longer sufficient, but request body in &lt;code&gt;GET&lt;/code&gt; requests is not
great either, which means you end-up sending non-mutating queries in &lt;code&gt;POST&lt;/code&gt;
requests (which is what Elasticsearch does). Is the API still RESTful at this
point?&lt;/p&gt;
&lt;p&gt;Either way, both clients and servers need to take extra care with
parsing, formatting and validating all these parameters. So much fun! 🙃
As an example, without proper validation and with uninitialised variables you can
easily get something like &lt;code&gt;/todos?offset=undefined&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Not easy to document and test&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://swagger.io&quot;&gt;Swagger&lt;/a&gt; mentioned above is probably the best tool
for this at the
moment, but it isn’t used widely enough. Much more frequently I see APIs
with documentation maintained separately. Not a big deal for a stable
widely used API, but much worse during development in an agile process.
Documentation stored separately means it’s frequently not updated at all,
especially if it’s a minor, but client-breaking change.&lt;/p&gt;
&lt;p&gt;If you don’t use Swagger,
it probably means you have specialised test infrastructure to maintain. There’s
also a much higher chance you need integration tests rather than unit-tests,
means testing both client and server-side code.&lt;/p&gt;
&lt;h3&gt;Relations and batch queries make it even more frustrating&lt;/h3&gt;
&lt;p&gt;This becomes a problem with much larger APIs, where you might have a number
of related collections. Let’s go further with an example of a todo-list app:
suppose every todo item can also belong to a project. Would you always want
to fetch all related projects at once? Probably not, but then there are more
query parameters to add. Maybe you don’t want to fetch all object fields at once.
What if the app needs projects to have owners and there’s a view with all this
data aggregated in addition to separate views displaying each collection separately? It’s either three separate HTTP requests or one complex request with all data fetched
at once for aggregation.&lt;/p&gt;
&lt;p&gt;Either way, there are complexity and performance tradeoffs, maintaining which in a
growing application brings more headaches than one would like.&lt;/p&gt;
&lt;h3&gt;You need every endpoint implemented both on server &lt;em&gt;and&lt;/em&gt; client&lt;/h3&gt;
&lt;p&gt;There is also a ton of libraries that can automatically generate a REST endpoint
with some help from &lt;a href=&quot;https://en.wikipedia.org/wiki/Object-relational_mapping&quot;&gt;ORMs&lt;/a&gt;
or direct database introspection. Even when those are
used, usually they aren’t very flexible or extensible. That means reimplementing
an endpoint from scratch if there is a need for custom parameters, advanced
filtering behaviour or just some smarter handling of request or response payload.&lt;/p&gt;
&lt;p&gt;Yet another task is consuming those endpoints in client code. It’s
great to use code-generation if you have it, but again it
seems to be not flexible enough. Even with helper libraries like
&lt;a href=&quot;https://github.com/moya/moya&quot;&gt;Moya&lt;/a&gt;, you stumble upon the same barrier: there
is a lot of custom behaviour to handle, which is caused by edge cases
mentioned above.&lt;/p&gt;
&lt;p&gt;If a dev team isn’t full-stack, communication between server and client teams
is crucial, even critical when there’s no machine-readable API spec.&lt;/p&gt;
&lt;h2&gt;And how’s GraphQL better?&lt;/h2&gt;
&lt;p&gt;With all issues discussed, I’m inclined to say that in
&lt;a href=&quot;https://en.wikipedia.org/wiki/Create,_read,_update_and_delete&quot;&gt;CRUD&lt;/a&gt; apps
it would be great to have a standard way to produce and consume APIs.
Common tooling and patterns, integrated testing and documentation infrastructure
would help with both technical and organisational issues.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://graphql.org&quot;&gt;GraphQL&lt;/a&gt; has a draft &lt;a href=&quot;https://en.wikipedia.org/wiki/Request_for_Comments&quot;&gt;RFC&lt;/a&gt;
spec and a &lt;a href=&quot;https://github.com/graphql/graphql-js&quot;&gt;reference implementation&lt;/a&gt;.
Also, check out &lt;a href=&quot;http://graphql.org/learn/&quot;&gt;GraphQL tutorial&lt;/a&gt;, which describes
most of the concepts you’d need to know.
There are implementations for different platforms, and there is
plenty of developer tools available as well, most notably &lt;a href=&quot;https://github.com/graphql/graphiql&quot;&gt;GraphiQL&lt;/a&gt;,
which bundles a nice API explorer with auto-completion and a browser for
documentation automatically generated from a GraphQL schema.&lt;/p&gt;
&lt;p&gt;In fact, I find GraphiQL indispensable.
It can help in solving communication issues between client and server-side teams I’ve
mentioned earlier. As soon as any changes are available in a GraphQL schema,
you’ll be able to see it in GraphiQL browser, same with embedded API documentation.
Now client and server teams can work together on API design in an even better way
with shorter iteration time and shared documentation that’s automatically generated and
visible to everyone on every API update.
To get a feeling of how these tools work check out a Star Wars API example that
is available as a
&lt;a href=&quot;http://graphql.org/swapi-graphql/&quot;&gt;GraphiQL live demo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Being able to specify object fields requested from a server allows clients to
fetch only data they need when they need. No more multiple heavy queries
issued to a rigid REST API, which are then stitched on the client
just to display it all at once in app UI. You are no longer restricted to
a set of endpoints, but have a schema of queries and mutations,
being able to cherry-pick fields and objects that a
client specifically requires. And a server only needs to implement top-level
schema objects this way.&lt;/p&gt;
&lt;h3&gt;A quick example&lt;/h3&gt;
&lt;p&gt;A GraphQL schema defines types that can be used in communication between servers and
clients. There are two special types that are also &lt;a href=&quot;http://graphql.org/learn/schema/#the-query-and-mutation-types&quot;&gt;core concepts&lt;/a&gt; in GraphQL:
&lt;code&gt;Query&lt;/code&gt; and &lt;code&gt;Mutation&lt;/code&gt;. Most of the time every request that is issued to a GraphQL
API is either
a &lt;code&gt;Query&lt;/code&gt; instance that is free of side-effects or a &lt;code&gt;Mutation&lt;/code&gt; instance that
modifies objects stored on the server.&lt;/p&gt;
&lt;p&gt;Now, sticking with our todo app example, consider this GraphQL schema:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;graphql&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;ID&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;!&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;TodoItem&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;ID&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;!&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;isCompleted&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;!&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;dueDate&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;Date&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;Project&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;TodoList&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;totalCount&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;!&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;TodoItem&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;]!&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;Query&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;allTodos&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;):&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;TodoList&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;!&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;todoByID&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;!):&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;TodoItem&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;Mutation&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;createTodo&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;TodoItem&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;!):&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;TodoItem&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;deleteTodo&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;!):&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;TodoItem&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;updateTodo&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;newItem&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;TodoItem&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;!):&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;TodoItem&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;

&lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;schema&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;Query&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-keyword&quot;&gt;mutation&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;Mutation&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;This &lt;code&gt;schema&lt;/code&gt; block at the bottom is special and defines root &lt;code&gt;Query&lt;/code&gt; and
&lt;code&gt;Mutation&lt;/code&gt; types as described previously. Otherwise, it’s pretty straightforward:
&lt;code&gt;type&lt;/code&gt; blocks define new types, each block contains field definitions with their
own types. Types can be non-optional, for example &lt;code&gt;String!&lt;/code&gt; field can’t ever
have &lt;code&gt;null&lt;/code&gt; value, while &lt;code&gt;String&lt;/code&gt; can. Fields can also have named parameters,
so &lt;code&gt;allTodos(limit: Int, offset: Int): TodoList!&lt;/code&gt; field of type &lt;code&gt;TodoList!&lt;/code&gt;
takes two optional parameters, while its own value is non-optional, meaning it will
always return a &lt;code&gt;TodoList&lt;/code&gt; instance that can’t be &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Then to query all todos with ids and names you’d write a query like this:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;graphql&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span class=&quot;cm-keyword&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;allTodos&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;cm-attribute&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;totalCount&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt; &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;{&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;id&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;description&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;cm-property&quot;&gt;isCompleted&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-ws&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;span &gt;
&lt;/span&gt;&lt;span class=&quot;cm-punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;GraphQL client library automatically parses and validates the query against
the schema and only then sends it to a GraphQL server. Note that &lt;code&gt;offset&lt;/code&gt; argument
to &lt;code&gt;allTodos&lt;/code&gt; field is absent. Being optional, its absence means it has &lt;code&gt;null&lt;/code&gt;
value. If the server supplies this sort of schema, it’s probably stated in
documentation that &lt;code&gt;null&lt;/code&gt; offset means that first page should be returned by
default. The response could look like this:&lt;/p&gt;

    &lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;
      &lt;pre class=&quot; cm-s-xcode&quot;
      &gt;&lt;code&gt;&lt;span &gt;{
&lt;/span&gt;&lt;span &gt;  &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;data&quot;&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;cm-string&quot;&gt;&quot;allTodos&quot;&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;cm-string&quot;&gt;&quot;totalCount&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;42&lt;/span&gt;&lt;span &gt;,
&lt;/span&gt;&lt;span &gt;      &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;items&quot;&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&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;1&lt;/span&gt;&lt;span &gt;,
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;write a blogpost&quot;&lt;/span&gt;&lt;span &gt;,
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;isCompleted&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;true&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&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;2&lt;/span&gt;&lt;span &gt;,
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;edit until looks good&quot;&lt;/span&gt;&lt;span &gt;,
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;isCompleted&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;true&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&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;2&lt;/span&gt;&lt;span &gt;,
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;proofread&quot;&lt;/span&gt;&lt;span &gt;,
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;isCompleted&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;false&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&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;4&lt;/span&gt;&lt;span &gt;,
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;publish on the website&quot;&lt;/span&gt;&lt;span &gt;,
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;isCompleted&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;false&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&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-number&quot;&gt;5&lt;/span&gt;&lt;span &gt;,
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-string&quot;&gt;&quot;share&quot;&lt;/span&gt;&lt;span &gt;,
&lt;/span&gt;&lt;span &gt;          &lt;/span&gt;&lt;span class=&quot;cm-string property&quot;&gt;&quot;isCompleted&quot;&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span class=&quot;cm-atom&quot;&gt;false&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&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;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
&lt;p&gt;If you drop &lt;code&gt;isCompleted&lt;/code&gt; field from the query, it’ll disappear from the result.
Or you can add &lt;code&gt;project&lt;/code&gt; field with its &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; to traverse the
relation. Add &lt;code&gt;offset&lt;/code&gt; parameter to &lt;code&gt;allTodos&lt;/code&gt; field to paginate, and so
&lt;code&gt;allTodos(count: 5, offset: 5)&lt;/code&gt; will return the second page. Helpfully
enough, you’ve got &lt;code&gt;totalCount&lt;/code&gt; field in the result, so now you know you’ve got
&lt;code&gt;42 / 5 = 9&lt;/code&gt; pages in total. But obviously, you can omit &lt;code&gt;totalCount&lt;/code&gt; if you don’t
need it. The query is in full control of what actual information will be received,
but underlying GraphQL infrastructure also ensures that all required fields and
parameters are there. If your GraphQL server is smart enough, it won’t run
database queries for fields you don’t need, and some libraries
are good enough to provide that for free.
Same with the rest
of mutations and queries in this schema: input is type-checked and
validated, and based on the query a GraphQL server knows what result
shape is expected.&lt;/p&gt;
&lt;p&gt;Under the hood, all communication runs
through a predefined URL (usually &lt;code&gt;/graphql&lt;/code&gt;) on a server with a simple &lt;code&gt;POST&lt;/code&gt;
request that contains the query serialised as a JSON payload. You almost never
have a need to be exposed to an abstraction layer this low though.&lt;/p&gt;
&lt;p&gt;Not too bad overall: we’ve got type-level validation issues taken care of,
pagination is also looking good and entity relations can be easily traversed
when needed. If you use some GraphQL -&gt; database query translation libraries
that are available, you wouldn’t
even need to write most of the database queries on the server.
Client-side libraries can unpack
a GraphQL response automatically as an object instance of a needed type quite easily,
as naturally the response shape is known upfront from the schema and queries.&lt;/p&gt;
&lt;h3&gt;GraphQL is this new hipster thing, a fad, right?&lt;/h3&gt;
&lt;p&gt;While &lt;a href=&quot;https://github.com/Netflix/falcor&quot;&gt;falcor by Netflix&lt;/a&gt; seemed to be
solving a similar problem, was published on GitHub a few months earlier than
GraphQL and came up on my personal radar earlier, it clearly looks like GraphQL
has won. Good tooling and strong industry support make it quite compelling.
Aside from a few minor glitches in some client libraries (that since have been
resolved), I can’t recommend highly enough to have a good look at what GraphQL
could offer in your tech stack. It is
&lt;a href=&quot;http://graphql.org/blog/production-ready/&quot;&gt;out of technical preview&lt;/a&gt; for
almost two years now and the ecosystem is growing even stronger. While Facebook
designed GraphQL, we see more and more big companies using it in their products
as well: &lt;a href=&quot;https://developer.github.com/v4/&quot;&gt;GitHub&lt;/a&gt;, &lt;a href=&quot;https://help.shopify.com/api/custom-storefronts/storefront-api/graphql-explorer&quot;&gt;Shopify&lt;/a&gt;,
&lt;a href=&quot;http://engineering.khanacademy.org/posts/creating-query-components-with-apollo.htm&quot;&gt;Khan Academy&lt;/a&gt;,
&lt;a href=&quot;https://dev-blog.apollodata.com/courseras-journey-to-graphql-a5ad3b77f39a&quot;&gt;Coursera&lt;/a&gt;,
and the list &lt;a href=&quot;http://graphql.org/users/&quot;&gt;is growing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There’s plenty of popular open-source projects that use GraphQL: this blog
is powered by &lt;a href=&quot;https://www.gatsbyjs.org&quot;&gt;Gatsby&lt;/a&gt; static site generator, which
translates results of GraphQL queries into data that are rendered into
an HTML file. If you’re on WordPress, a &lt;a href=&quot;https://wpgraphql.com&quot;&gt;GraphQL API&lt;/a&gt;
is available for it as well. &lt;a href=&quot;https://github.com/reactioncommerce/reaction&quot;&gt;Reaction Commerce&lt;/a&gt; is an open-source alternative
to Shopify that’s also powered by GraphQL.&lt;/p&gt;
&lt;p&gt;A few GraphQL libraries worth mentioning again are &lt;a href=&quot;https://www.graphile.org/postgraphile/&quot;&gt;PostGraphile&lt;/a&gt; and &lt;a href=&quot;https://www.apollographql.com/client&quot;&gt;Apollo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you use PostgreSQL as your database on the backend, PostGraphile is able to
scan a SQL schema and automatically generate a GraphQL schema with an implementation.
You get all common CRUD operations exposed as queries and mutations for all tables.
It may look like it’s an ORM, but it isn’t: you’re in full control of how your
database schema is designed, and what indices are used. Great thing is that
PostGraphile also exposes views and functions as queries and mutations, so if
there is particularly complex SQL query that you’d like to map to a GraphQL
field, just create that SQL view or function and it’ll appear automatically
in GraphQL schema. With advanced Postgres features like
&lt;a href=&quot;https://www.postgresql.org/docs/10/static/ddl-rowsecurity.html&quot;&gt;row-level security&lt;/a&gt;,
you can get complex access control logic implemented with only a few SQL policies
to write. PostGraphile even has awesome things like schema documentation
&lt;a href=&quot;https://www.graphile.org/postgraphile/postgresql-schema-design/#table-documentation&quot;&gt;generated automatically from Postgres comments&lt;/a&gt; 🤩.&lt;/p&gt;
&lt;p&gt;In turn, Apollo
provides both client libraries for multiple platforms and code generators
that produce type definitions in most popular programming
languages, including TypeScript and Swift. In general, I find Apollo much simpler
and manageable to use than, for example, &lt;a href=&quot;https://github.com/facebook/relay&quot;&gt;Relay&lt;/a&gt;.
Thanks to simple architecture of Apollo client library, I was able to slowly
transition an app that used &lt;a href=&quot;http://reactjs.com&quot;&gt;React.js&lt;/a&gt; with
&lt;a href=&quot;https://redux.js.org&quot;&gt;Redux&lt;/a&gt; to &lt;a href=&quot;https://github.com/apollographql/react-apollo&quot;&gt;React Apollo&lt;/a&gt;, component by component and only
when it made sense to do so. Same with native iOS apps,
&lt;a href=&quot;https://github.com/apollographql/apollo-ios&quot;&gt;Apollo iOS&lt;/a&gt; is a relatively lightweight
library that’s easy to use.&lt;/p&gt;
&lt;p&gt;In a future article, I’d like to describe some of my experience with this
tech stack. In the meantime, shoot me a
&lt;a href=&quot;https://twitter.com/maxdesiatov&quot;&gt;message on Twitter&lt;/a&gt; about your
experience with GraphQL or if you’re just interested how it could work in your
app 👋.&lt;/p&gt;</content:encoded></item></channel></rss>