<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Cocoaphony]]></title>
  <link href="https://robnapier.net/atom.xml" rel="self"/>
  <link href="https://robnapier.net/"/>
  <updated>2025-05-15T18:13:46-04:00</updated>
  <id>https://robnapier.net/</id>
  <author>
    <name><![CDATA[Rob Napier]]></name>
    <email><![CDATA[rob@neverwood.org]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[A Mockery of Types]]></title>
    <link href="https://robnapier.net/mockery"/>
    <updated>2025-05-14T21:21:00-04:00</updated>
    <id>https://robnapier.net/mockery</id>
    <content type="html"><![CDATA[<p>I’m going to talk about testing over the next few posts. If you’ve talked to me at any length over the last several years, you know I’ve been thinking a lot about testing, and I have somewhat unorthodox opinions. Unorthodox enough that I really haven’t wanted to write them down because I’m really not trying to start an argument. If your approach to testing works for you and your team, I think you’re doing it right and I don’t think you should change just because I do it a different way.</p>

<p>But if you and your team struggle with testing and you think it’s because you lack the discipline to “do things right,” I’d like to offer another way of thinking about testing that has worked very well for many years, for several teams, and in multiple languages. In this series I’m going to focus specifically on iOS development working in Swift. Some topics are different in other environments. I might touch on those eventually, but to keep this already sprawling topic bounded, I’m going to stick to client-side Swift for now.</p>

<p>So none of this may apply to you. But if you feel that your current testing approach isn’t working, I’d like to offer another option:</p>

<p><em>Mock as little as you can. Mock only at the edges. Minimize dependency injection. Test real code.</em></p>

<!-- more -->

<p>This is the point in the conversation at which many a good and wise friend has, with great kindness, called me an idiot. And before I’m done, you might too. And that’s fine. If your fancy DI framework is working for you, you shouldn’t abandon it. Maybe listen to some of my philosophical points and ignore the rest. Or ignore it all. I’m warning you up front where this is headed.</p>

<p>But the best thing I’ve done for testing in multiple code bases has been to delete nearly all the mocks and mostly remove dependency injection. In the process, I’ve also made production code better. I’ve spent the last few months removing mocks from my current project while also improving test code coverage by tens of thousands of lines. Tests are simpler to write and they actually test real things. It’s possible to do a lot of testing with very little mocking.</p>

<p>I want to start this series with a concrete example: a Keychain wrapper. We’ve all used them. I’ve worked with many on several teams (and sometimes several on the same team), and this example is based on lessons learned from all of them.</p>

<p><span class="pullquote-right" data-pullquote="We need to be able to test things that aren&#8217;t perfect.">
You’re going to look at this wrapper and think “that’s not an ideal design,” and you’re right. But it’s the kind of design you’ll find in real code bases. We need to be able to test things that aren’t perfect. You don’t need to read it all now. The comments at the top are enough, and I’ll explain the API along the way.
</span></p>

<p><a href="https://github.com/rnapier/testing/blob/main/mockery/Stage1/Keychain/Sources/Keychain/Keychain.swift"><em>Source code</em></a></p>

<div class="language-swift scroll highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">/// A Keychain wrapper that offers key/value storage with the following features:</span>
<span class="c1">///</span>
<span class="c1">/// * Takes an identifier to maintain separate stores</span>
<span class="c1">/// * Each Keychain offers independent key/value storage</span>
<span class="c1">/// * Caches values in memory for performance</span>
<span class="c1">/// * Allows reading and writing Data directly</span>
<span class="c1">/// * Encodes Strings as UTF-8</span>
<span class="c1">/// * Encodes JSONSerialization-compatible types (except String and Data) as JSON</span>
<span class="c1">/// * Supports "reset" to delete all keys for this identifier</span>
<span class="c1">///</span>
<span class="kd">public</span> <span class="kd">actor</span> <span class="kt">Keychain</span> <span class="p">{</span>
  <span class="kd">public</span> <span class="k">let</span> <span class="nv">identifier</span><span class="p">:</span> <span class="kt">String</span>
  <span class="kd">private</span> <span class="k">var</span> <span class="nv">cache</span><span class="p">:</span> <span class="p">[</span><span class="kt">String</span><span class="p">:</span> <span class="kt">Data</span><span class="p">]</span> <span class="o">=</span> <span class="p">[:]</span>

  <span class="kd">public</span> <span class="nf">init</span><span class="p">(</span><span class="nv">identifier</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="p">{</span> <span class="k">self</span><span class="o">.</span><span class="n">identifier</span> <span class="o">=</span> <span class="n">identifier</span> <span class="p">}</span>

  <span class="c1">// MARK: - Data Operations</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">data</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span><span class="p">?</span> <span class="p">{</span>
    <span class="c1">// First check the cache</span>
    <span class="k">if</span> <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="p">{</span>
      <span class="k">return</span> <span class="n">data</span>
    <span class="p">}</span>

    <span class="c1">// That terrible `SecItemCopyMatching` call you all know...</span>
    <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="k">try</span> <span class="nf">_data</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>

    <span class="c1">// And cache it for later</span>
    <span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">data</span>
    <span class="k">return</span> <span class="n">data</span>
  <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="c1">// Set it to the cache and to system keychain</span>
    <span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">data</span>
    <span class="k">try</span> <span class="nf">_set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">removeData</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="c1">// Remove it from the cache and the system keychain</span>
    <span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="kc">nil</span>
    <span class="k">try</span> <span class="nf">_removeData</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">reset</span><span class="p">()</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="c1">// Clear the cache and delete all keys for this identifier</span>
    <span class="n">cache</span> <span class="o">=</span> <span class="p">[:]</span>
    <span class="k">try</span> <span class="nf">_reset</span><span class="p">()</span>
  <span class="p">}</span>

  <span class="c1">// MARK: - String Operations -- Encode as UTF-8</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">string</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">String</span><span class="p">?</span> <span class="p">{</span>
    <span class="k">guard</span> <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="k">try</span> <span class="nf">data</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">nil</span> <span class="p">}</span>
    <span class="k">return</span> <span class="kt">String</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nv">encoding</span><span class="p">:</span> <span class="o">.</span><span class="n">utf8</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="k">try</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">utf8</span><span class="p">),</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="c1">// MARK: - JSONSerialization Operations</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">value</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Any</span><span class="p">?</span> <span class="p">{</span>
    <span class="k">guard</span> <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="k">try</span> <span class="nf">data</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">nil</span> <span class="p">}</span>
    <span class="k">return</span> <span class="k">try</span> <span class="kt">JSONSerialization</span><span class="o">.</span><span class="nf">jsonObject</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nv">options</span><span class="p">:</span> <span class="p">[</span><span class="o">.</span><span class="n">fragmentsAllowed</span><span class="p">])</span>
  <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">value</span><span class="p">:</span> <span class="kt">Any</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="k">try</span> <span class="kt">JSONSerialization</span><span class="o">.</span><span class="nf">data</span><span class="p">(</span><span class="nv">withJSONObject</span><span class="p">:</span> <span class="n">value</span><span class="p">,</span> <span class="nv">options</span><span class="p">:</span> <span class="p">[</span><span class="o">.</span><span class="n">fragmentsAllowed</span><span class="p">])</span>
    <span class="k">try</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="c1">// MARK: - Public Extensions for Common Types (Bool, Int)</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">bool</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Bool</span><span class="p">?</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">value</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="k">as?</span> <span class="kt">Bool</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">bool</span><span class="p">:</span> <span class="kt">Bool</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">set</span><span class="p">(</span><span class="nv">value</span><span class="p">:</span> <span class="n">bool</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">int</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Int</span><span class="p">?</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">value</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="k">as?</span> <span class="kt">Int</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">int</span><span class="p">:</span> <span class="kt">Int</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">set</span><span class="p">(</span><span class="nv">value</span><span class="p">:</span> <span class="n">int</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>

  <span class="c1">// MARK: - All those horrible low-level SecItem... wrappers that I'm not going to bore you with</span>

  <span class="kd">private</span> <span class="kd">func</span> <span class="nf">_data</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span><span class="p">?</span> <span class="p">{</span> 
    <span class="c1">// ...</span>
  <span class="p">}</span>
  <span class="kd">private</span> <span class="kd">func</span> <span class="nf">_set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="c1">// ...</span>
  <span class="p">}</span>
  <span class="kd">private</span> <span class="kd">func</span> <span class="nf">_removeData</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="c1">// ...</span>
  <span class="p">}</span>
  <span class="kd">private</span> <span class="kd">func</span> <span class="nf">_reset</span><span class="p">()</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="c1">// ...</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Some key points to this code that will come up later:</p>

<ul>
  <li>Calling <code class="language-plaintext highlighter-rouge">set(string:forKey:)</code> encodes the value differently than <code class="language-plaintext highlighter-rouge">set(value:forKey:)</code> when passing a <code class="language-plaintext highlighter-rouge">String</code>. In some cases, a mismatch will lead to returning the wrong value (quoted vs not-quoted). In other cases it may return <code class="language-plaintext highlighter-rouge">nil</code>. “Well that’s awkward. Let’s fix it!” But remember, this code has shipped. Millions of keys have already been written to user keychains. If you change the encoding, you’ll need to write a migrator. There may be other code that has hacked around the current behavior and will break if you change it (ask me why I think that might happen…). Before you go redesigning a critical piece of persistent storage, it sure would be nice to have tests, right? As much as we can, we want a testing approach that can deal with things as they are, not just how they should be.<sup id="fnref:why"><a href="#fn:why" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></li>
</ul>

<ul>
  <li>This code cannot be called from a unit test on any platform but macOS if the test lives in an SPM package (rather than a hosted application). To access the system keychain, even on Simulator, requires an entitlements file, and SPM can’t provide it. That means that some kind of “mocking” solution is absolutely required for any non-macOS SPM code that relies on <code class="language-plaintext highlighter-rouge">Keychain</code>. It’s literally impossible to test otherwise. The point of this series isn’t “never mock.” It’s to reduce mocking as much as we can.</li>
</ul>

<p><span class="pullquote-right" data-pullquote="We do not write tests for virtue&#8217;s sake.">
For the moment, I want to ignore how we test <code class="language-plaintext highlighter-rouge">Keychain</code> itself. Maybe it’s been around for years and you’ve never had any bugs from it. Should you even write tests at that point? Meh? We do not write tests for virtue’s sake. They are work, and we need to have a reason to write them. In a later post I’ll discuss the many different reasons to write tests, but chasing ever-higher code coverage isn’t one of them.
</span></p>

<p>I want to start by testing things that <em>use</em> <code class="language-plaintext highlighter-rouge">Keychain</code>. Since using <code class="language-plaintext highlighter-rouge">Keychain</code> completely breaks unit tests for iOS, we need to do something.</p>

<p>So, I’m going to reach for the tool you’re all thinking of. <a href="https://robnapier.net/a-mockery-of-protocols">It’s the wrong tool</a>, but it’s <a href="https://robnapier.net/start-with-a-protocol">where we all start</a>. I’m going to make a protocol!</p>

<h2 id="abusing-protocols-for-tests-and-dubious-profit">Abusing Protocols for Tests and (Dubious) Profit</h2>

<p>Here we go. Each public method becomes a protocol requirement:</p>

<p><a href="https://github.com/rnapier/testing/blob/main/mockery/Stage2/Keychain/Sources/Keychain/KeychainProtocol.swift"><em>Source code</em></a></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">protocol</span> <span class="kt">KeychainProtocol</span><span class="p">:</span> <span class="kt">Actor</span> <span class="p">{</span>
  <span class="kd">func</span> <span class="nf">data</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span><span class="p">?</span>
  <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span>
  <span class="kd">func</span> <span class="nf">removeData</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span>
  <span class="kd">func</span> <span class="nf">reset</span><span class="p">()</span> <span class="k">throws</span>

  <span class="kd">func</span> <span class="nf">string</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">String</span><span class="p">?</span>
  <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span>

  <span class="kd">func</span> <span class="nf">value</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Any</span><span class="p">?</span>
  <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">value</span><span class="p">:</span> <span class="kt">Any</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span>

  <span class="kd">func</span> <span class="nf">bool</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Bool</span><span class="p">?</span>
  <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">bool</span><span class="p">:</span> <span class="kt">Bool</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span>

  <span class="kd">func</span> <span class="nf">int</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Int</span><span class="p">?</span>
  <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">int</span><span class="p">:</span> <span class="kt">Int</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span>
<span class="p">}</span>
</code></pre></div></div>
<p>And we build a mock. Because we always need a mock that implements every single part of the subject:</p>

<p><a href="https://github.com/rnapier/testing/blob/main/mockery/Stage2/Keychain/Sources/Keychain/MockKeychain.swift"><em>Source code</em></a></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">actor</span> <span class="kt">MockKeychain</span><span class="p">:</span> <span class="kt">KeychainProtocol</span> <span class="p">{</span>
  <span class="kd">private</span> <span class="k">var</span> <span class="nv">storage</span><span class="p">:</span> <span class="p">[</span><span class="kt">String</span><span class="p">:</span> <span class="kt">Data</span><span class="p">]</span> <span class="o">=</span> <span class="p">[:]</span>

  <span class="c1">//</span>
  <span class="c1">// Data accessors</span>
  <span class="c1">//</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">data</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span><span class="p">?</span> <span class="p">{</span> <span class="n">storage</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span> <span class="n">storage</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">data</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">removeData</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span> <span class="n">storage</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="kc">nil</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">reset</span><span class="p">()</span> <span class="k">throws</span> <span class="p">{</span> <span class="n">storage</span><span class="o">.</span><span class="nf">removeAll</span><span class="p">()</span> <span class="p">}</span>

  <span class="c1">//</span>
  <span class="c1">// Codable accessors</span>
  <span class="c1">//</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">string</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">String</span><span class="p">?</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">decode</span><span class="p">(</span><span class="nv">key</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">store</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">bool</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Bool</span><span class="p">?</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">decode</span><span class="p">(</span><span class="nv">key</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">bool</span><span class="p">:</span> <span class="kt">Bool</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">store</span><span class="p">(</span><span class="n">bool</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">int</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Int</span><span class="p">?</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">decode</span><span class="p">(</span><span class="nv">key</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">int</span><span class="p">:</span> <span class="kt">Int</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">store</span><span class="p">(</span><span class="n">int</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>

  <span class="c1">//</span>
  <span class="c1">// JSONSerialization accessors</span>
  <span class="c1">//</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">value</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Any</span><span class="p">?</span> <span class="p">{</span>
    <span class="k">guard</span> <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="n">storage</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">nil</span> <span class="p">}</span>
    <span class="k">return</span> <span class="k">try</span> <span class="kt">JSONSerialization</span><span class="o">.</span><span class="nf">jsonObject</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nv">options</span><span class="p">:</span> <span class="p">[</span><span class="o">.</span><span class="n">fragmentsAllowed</span><span class="p">])</span>
  <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">value</span><span class="p">:</span> <span class="kt">Any</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="n">storage</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="k">try</span> <span class="kt">JSONSerialization</span><span class="o">.</span><span class="nf">data</span><span class="p">(</span><span class="nv">withJSONObject</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nv">options</span><span class="p">:</span> <span class="p">[</span><span class="o">.</span><span class="n">fragmentsAllowed</span><span class="p">])</span>
  <span class="p">}</span>

  <span class="c1">//</span>
  <span class="c1">// Private helpers</span>
  <span class="c1">//</span>
  <span class="kd">private</span> <span class="kd">func</span> <span class="n">decode</span><span class="o">&lt;</span><span class="kt">T</span><span class="p">:</span> <span class="kt">Codable</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="nv">as</span><span class="p">:</span> <span class="kt">T</span><span class="o">.</span><span class="k">Type</span> <span class="o">=</span> <span class="kt">T</span><span class="o">.</span><span class="k">self</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">T</span><span class="p">?</span> <span class="p">{</span>
    <span class="k">guard</span> <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="n">storage</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">nil</span> <span class="p">}</span>
    <span class="k">return</span> <span class="k">try</span> <span class="kt">JSONDecoder</span><span class="p">()</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">T</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">from</span><span class="p">:</span> <span class="n">data</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="kd">private</span> <span class="kd">func</span> <span class="n">store</span><span class="o">&lt;</span><span class="kt">T</span><span class="p">:</span> <span class="kt">Codable</span><span class="o">&gt;</span><span class="p">(</span><span class="n">_</span> <span class="nv">value</span><span class="p">:</span> <span class="kt">T</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="n">storage</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="k">try</span> <span class="kt">JSONEncoder</span><span class="p">()</span><span class="o">.</span><span class="nf">encode</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="make-your-mocks-small">Make your mocks small</h2>

<p>This is exactly how I’ve seen this problem solved so many times. And now that I’ve written it out myself, I must cry a little. Give me a moment. Please… stop doing this. You can have your mocks. Mock if it makes you happy, but not like this.</p>

<p>If a protocol is large and has basically the same interface as its implementations, then it’s not a protocol, it’s an abstract class. And Swift protocols are not abstract classes. The point of protocols is to adapt types to algorithms. It is not to <a href="https://en.cppreference.com/w/cpp/language/pimpl">recreate the pImpl pattern</a>. You shouldn’t have to modify the protocol and the mock every single time you touch the subject’s API.</p>

<p>A protocol, even for a mock, should capture the parts that vary between implementations, not the parts that are the same. Here’s what actually varies, the parts that read and write data to storage:</p>

<p><a href="https://github.com/rnapier/testing/blob/main/mockery/Stage3/Keychain/Sources/Keychain/KeychainStorage.swift"><em>Source code</em></a></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">protocol</span> <span class="kt">KeychainStorage</span><span class="p">:</span> <span class="kt">Actor</span> <span class="p">{</span>
  <span class="kd">func</span> <span class="nf">data</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span><span class="p">?</span>
  <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span>
  <span class="kd">func</span> <span class="nf">removeData</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span>
  <span class="kd">func</span> <span class="nf">reset</span><span class="p">()</span> <span class="k">throws</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The vast majority of <code class="language-plaintext highlighter-rouge">Keychain</code> has nothing to do with the system keychain. Most of the methods implement encoding logic, “business” logic. There is nothing about encoding logic that needs mocking, so it shouldn’t be mocked. You want to test it! Instead, that logic should be moved to a protocol extension and shared between <code class="language-plaintext highlighter-rouge">Keychain</code> and its mock.</p>

<div class="language-swift scroll highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">KeychainStorage</span> <span class="p">{</span>
  <span class="c1">// MARK: - String Operations -- Encode as UTF-8</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">string</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">String</span><span class="p">?</span> <span class="p">{</span>
    <span class="k">guard</span> <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="k">try</span> <span class="nf">data</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">nil</span> <span class="p">}</span>
    <span class="k">return</span> <span class="kt">String</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nv">encoding</span><span class="p">:</span> <span class="o">.</span><span class="n">utf8</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="k">try</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">utf8</span><span class="p">),</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="c1">// MARK: - JSONSerialization Operations</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">value</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Any</span><span class="p">?</span> <span class="p">{</span>
    <span class="k">guard</span> <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="k">try</span> <span class="nf">data</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">nil</span> <span class="p">}</span>
    <span class="k">return</span> <span class="k">try</span> <span class="kt">JSONSerialization</span><span class="o">.</span><span class="nf">jsonObject</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nv">options</span><span class="p">:</span> <span class="p">[</span><span class="o">.</span><span class="n">fragmentsAllowed</span><span class="p">])</span>
  <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">value</span><span class="p">:</span> <span class="kt">Any</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="k">try</span> <span class="kt">JSONSerialization</span><span class="o">.</span><span class="nf">data</span><span class="p">(</span><span class="nv">withJSONObject</span><span class="p">:</span> <span class="n">value</span><span class="p">,</span> <span class="nv">options</span><span class="p">:</span> <span class="p">[</span><span class="o">.</span><span class="n">fragmentsAllowed</span><span class="p">])</span>
    <span class="k">try</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="c1">// MARK: - Public Extensions for Common Types (Bool, Int)</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">bool</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Bool</span><span class="p">?</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">value</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="k">as?</span> <span class="kt">Bool</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">bool</span><span class="p">:</span> <span class="kt">Bool</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">set</span><span class="p">(</span><span class="nv">value</span><span class="p">:</span> <span class="n">bool</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">int</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Int</span><span class="p">?</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">value</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="k">as?</span> <span class="kt">Int</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">int</span><span class="p">:</span> <span class="kt">Int</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span> <span class="k">try</span> <span class="nf">set</span><span class="p">(</span><span class="nv">value</span><span class="p">:</span> <span class="n">int</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Now the entire mock looks like this:</p>

<p><a href="https://github.com/rnapier/testing/blob/main/mockery/Stage3/Keychain/Sources/Keychain/MockKeychain.swift"><em>Source code</em></a></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">actor</span> <span class="kt">MockKeychain</span><span class="p">:</span> <span class="kt">KeychainStorage</span> <span class="p">{</span>
  <span class="kd">private</span> <span class="k">var</span> <span class="nv">cache</span><span class="p">:</span> <span class="p">[</span><span class="kt">String</span><span class="p">:</span> <span class="kt">Data</span><span class="p">]</span> <span class="o">=</span> <span class="p">[:]</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">data</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span><span class="p">?</span> <span class="p">{</span> <span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span> <span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">data</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">removeData</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span> <span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="kc">nil</span> <span class="p">}</span>
  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">reset</span><span class="p">()</span> <span class="k">throws</span> <span class="p">{</span> <span class="n">cache</span><span class="o">.</span><span class="nf">removeAll</span><span class="p">()</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="two-roads-diverged-and-thats-bad">Two roads diverged… and that’s bad</h2>

<p>Mocks that duplicate a large subject’s API do it one of two ways:</p>

<ul>
  <li>They copy a lot of the code from the subject.</li>
  <li>They <em>don’t</em> copy a lot of the code from the subject.</li>
</ul>

<p>Above is an example where I didn’t copy a lot of code from the subject. I reimplemented it in an easy way, which is the most common way I see mocks implemented. I used <code class="language-plaintext highlighter-rouge">JSONEncoder</code> for everything rather than having custom logic for <code class="language-plaintext highlighter-rouge">String</code>. Since it’s symmetrical, it “works,” but the mock has diverged from the thing it’s pretending to be. Consider this code:</p>

<p><a href="https://github.com/rnapier/testing/blob/main/mockery/Stage3/Keychain/Tests/KeychainTests/KeychainTests.swift"><em>Source code</em></a></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">@Test</span> <span class="kd">func</span> <span class="nf">testCrossStorage</span><span class="p">()</span> <span class="k">async</span> <span class="k">throws</span> <span class="p">{</span>
  <span class="c1">// Write it as String</span>
  <span class="k">try</span> <span class="k">await</span> <span class="n">keychain</span><span class="o">.</span><span class="nf">set</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="s">"abc"</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="s">"key"</span><span class="p">)</span>

  <span class="c1">// Read it as data and decode manually</span>
  <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="k">try</span> <span class="k">#require</span><span class="p">(</span><span class="k">try</span> <span class="k">await</span> <span class="n">keychain</span><span class="o">.</span><span class="nf">data</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="s">"key"</span><span class="p">))</span>
  <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="kt">String</span><span class="p">(</span><span class="nv">decoding</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nv">as</span><span class="p">:</span> <span class="kt">UTF8</span><span class="o">.</span><span class="k">self</span><span class="p">)</span>

  <span class="cp">#expect(result == "abc")  // testCrossStorage(): Expectation failed: (result → ""abc"") == "abc"</span>
<span class="p">}</span>
</code></pre></div></div>
<p>This test works with the real <code class="language-plaintext highlighter-rouge">Keychain</code>, but it fails with the mock that uses <code class="language-plaintext highlighter-rouge">Codable</code> internally. Nothing here is invalid. It’s a weird way to use the system, but it’s legal and even useful. If the caller wants the value as <code class="language-plaintext highlighter-rouge">Data</code> in order to write it to a file, there’s no reason to round-trip it through <code class="language-plaintext highlighter-rouge">String</code>. They may rely on the fact that they know how it’s encoded.</p>

<p><span class="pullquote-right" data-pullquote="Test your product, not your mocks.">
That’s bad, but the test will fail, so at least it would be caught. The real problem is the reverse. Someone designs their system based on the mock’s behavior <em>rather than what you ship</em>. All the tests will pass, but it will fail in the field. That’s the worst case. You spend all this time building mocks, writing tests, running tests, and what do you get for all that? A bug that’s a real pain to figure out because your tests are lying to you. Test your product, not your mocks.
</span></p>

<p>Of course, instead of re-implementing everything for the mock, I could have copied a lot more code from <code class="language-plaintext highlighter-rouge">Keychain</code> into <code class="language-plaintext highlighter-rouge">MockKeychain</code>, but that’s not any better. It means that today they’re aligned, but as <code class="language-plaintext highlighter-rouge">Keychain</code> evolves the two will almost certainly diverge. If the tests don’t verify all observable behaviors (and that takes a lot more than just “100% code coverage”), then you’ll have the same situation.</p>

<p>Instead, I made the mock protocol small. Just 4 methods:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">protocol</span> <span class="kt">KeychainStorage</span><span class="p">:</span> <span class="kt">Actor</span> <span class="p">{</span>
  <span class="kd">func</span> <span class="nf">data</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span><span class="p">?</span>
  <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span>
  <span class="kd">func</span> <span class="nf">removeData</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span>
  <span class="kd">func</span> <span class="nf">reset</span><span class="p">()</span> <span class="k">throws</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Get, set, delete, reset. Those are what the rest of the code needs to operate. Those are exactly the methods I pulled out into some private helpers because they’re kind of ugly.</p>

<h2 id="no-smaller-than-that">No, smaller than that</h2>

<p>But now that we’ve pulled these methods into a protocol, why don’t we go further. We could pull them into their own type. What if <code class="language-plaintext highlighter-rouge">Keychain</code> HAS-A storage rather than IS-A storage?</p>

<p>So the storage is just a struct:</p>

<p><a href="https://github.com/rnapier/testing/blob/main/mockery/Stage4/Keychain/Sources/Keychain/KeychainStorage.swift"><em>Source code</em></a></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">KeychainStorage</span> <span class="p">{</span>
  <span class="k">let</span> <span class="nv">identifier</span><span class="p">:</span> <span class="kt">String</span>

  <span class="nf">init</span><span class="p">(</span><span class="nv">identifier</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="p">{</span> <span class="k">self</span><span class="o">.</span><span class="n">identifier</span> <span class="o">=</span> <span class="n">identifier</span><span class="p">}</span>

  <span class="c1">// MARK: - All those horrible low-level SecItem... wrappers that I'm not going to bore you with</span>

  <span class="kd">func</span> <span class="nf">data</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span><span class="p">?</span> <span class="p">{</span> 
    <span class="c1">// ...</span>
  <span class="p">}</span>
  <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="c1">// ...</span>
  <span class="p">}</span>
  <span class="kd">func</span> <span class="nf">removeData</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="c1">// ...</span>
  <span class="p">}</span>
  <span class="kd">func</span> <span class="nf">reset</span><span class="p">()</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="c1">// ...</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And the <code class="language-plaintext highlighter-rouge">Keychain</code> uses it.</p>

<p><a href="https://github.com/rnapier/testing/blob/main/mockery/Stage4/Keychain/Sources/Keychain/Keychain.swift"><em>Source code</em></a></p>

<div class="language-swift scroll highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">actor</span> <span class="kt">Keychain</span> <span class="p">{</span>
  <span class="kd">private</span> <span class="k">var</span> <span class="nv">cache</span><span class="p">:</span> <span class="p">[</span><span class="kt">String</span><span class="p">:</span> <span class="kt">Data</span><span class="p">]</span> <span class="o">=</span> <span class="p">[:]</span>
  <span class="kd">private</span> <span class="k">let</span> <span class="nv">storage</span><span class="p">:</span> <span class="kt">KeychainStorage</span><span class="p">?</span>

  <span class="kd">public</span> <span class="nf">init</span><span class="p">(</span><span class="nv">identifier</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">self</span><span class="o">.</span><span class="n">storage</span> <span class="o">=</span> <span class="kt">KeychainStorage</span><span class="p">(</span><span class="nv">identifier</span><span class="p">:</span> <span class="n">identifier</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="c1">// For tests, but we'll talk about this much more.</span>
  <span class="nf">init</span><span class="p">(</span><span class="nv">storage</span><span class="p">:</span> <span class="kt">KeychainStorage</span><span class="p">?)</span> <span class="p">{</span>
    <span class="k">self</span><span class="o">.</span><span class="n">storage</span> <span class="o">=</span> <span class="n">storage</span>
  <span class="p">}</span>

  <span class="c1">// MARK: - Data Operations</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">data</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Data</span><span class="p">?</span> <span class="p">{</span>
    <span class="k">if</span> <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="p">{</span>
      <span class="k">return</span> <span class="n">data</span>
    <span class="p">}</span>

    <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="k">try</span> <span class="n">storage</span><span class="p">?</span><span class="o">.</span><span class="nf">data</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
    <span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">data</span>
    <span class="k">return</span> <span class="n">data</span>
  <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">data</span>
    <span class="k">try</span> <span class="n">storage</span><span class="p">?</span><span class="o">.</span><span class="nf">set</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">removeData</span><span class="p">(</span><span class="k">for</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="n">cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="kc">nil</span>
    <span class="k">try</span> <span class="n">storage</span><span class="p">?</span><span class="o">.</span><span class="nf">removeData</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="kd">public</span> <span class="kd">func</span> <span class="nf">reset</span><span class="p">()</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="n">cache</span> <span class="o">=</span> <span class="p">[:]</span>
    <span class="k">try</span> <span class="n">storage</span><span class="p">?</span><span class="o">.</span><span class="nf">reset</span><span class="p">()</span>
  <span class="p">}</span>

  <span class="c1">// ...</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Wait, where did the protocol go? What about mocking? Look closely:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="k">let</span> <span class="nv">storage</span><span class="p">:</span> <span class="kt">KeychainStorage</span><span class="p">?</span>
</code></pre></div></div>

<p>The storage is optional. What happens in this code if it’s nil? Well, it reads and writes to a local dictionary, and doesn’t do anything with the system keychain. Isn’t that exactly what <code class="language-plaintext highlighter-rouge">KeychainMock</code> does?</p>

<p><code class="language-plaintext highlighter-rouge">Keychain</code> is its own mock! All you need to do is set <code class="language-plaintext highlighter-rouge">storage = nil</code>. And if you modify <code class="language-plaintext highlighter-rouge">Keychain</code>, its mock automatically matches because it’s the same thing. The only thing we’ve removed is the little bit that we didn’t want during testing: writing to the real keychain.</p>

<p>This is a shockingly powerful pattern. I call it “self-mocking” and I use it a lot. A whole lot. <code class="language-plaintext highlighter-rouge">Keychain</code> is possibly the most perfect example of it, but many types can benefit from this approach, particularly when you add a few more techniques.</p>

<p>And that’s what this series looks like. This is the simplest form of it, and I’m skipping a few very important details that I’ll discuss soon, like “how do you set <code class="language-plaintext highlighter-rouge">storage = nil</code> without a DI system?” Yeah, that’s an important question.<sup id="fnref:tikitu"><a href="#fn:tikitu" class="footnote" rel="footnote" role="doc-noteref">2</a></sup> And there will be philosophy. So much philosophy. Stay tuned.</p>

<p><a href="https://github.com/rnapier/testing"><em>The repository</em></a></p>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:why">
      <p>“Why would anyone build it this way?!?!?” While I’ve invented this version for this article, it’s based on many similar ones I’ve worked with and it’s very natural to get here. The <code class="language-plaintext highlighter-rouge">Data</code> and <code class="language-plaintext highlighter-rouge">String</code> interfaces are built first and are all anyone needs at the time. Later, the <code class="language-plaintext highlighter-rouge">Any</code> interface is added to deal with <code class="language-plaintext highlighter-rouge">[String: Any]</code> dictionaries from the networking stack. It happens to work fine for things like <code class="language-plaintext highlighter-rouge">Int</code> and <code class="language-plaintext highlighter-rouge">Bool</code>, so people start to use the <code class="language-plaintext highlighter-rouge">Any</code> interface for those, and then convenience methods are added. Then someone wants <code class="language-plaintext highlighter-rouge">Codable</code> support, but is afraid to modify the widely used <code class="language-plaintext highlighter-rouge">Keychain</code>, and so adds it locally in their module. Someone else does the same in another module, but instead of <code class="language-plaintext highlighter-rouge">JSONEncoder</code>, uses <code class="language-plaintext highlighter-rouge">PropertyListEncoder</code>. So now if you try to merge all the different interfaces, you’ll find they’re incompatible. <a href="https://martinfowler.com/bliki/Yagni.html">Yagni</a> tells us not to build features we don’t need yet. We only need <code class="language-plaintext highlighter-rouge">Data</code> and <code class="language-plaintext highlighter-rouge">String</code>, and then <code class="language-plaintext highlighter-rouge">[String: Any]</code>, and then just one module needs <code class="language-plaintext highlighter-rouge">Codable</code>, and then… Unifying at any point would introduce risky data migration for thousands of users that no project wants to add to their schedule. And that, my friends, is a downside of yagni that doesn’t get enough discussion. But that’s another blog post. <a href="#fnref:why" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:tikitu">
      <p>Thanks to <a href="https://mastodon.social/@tikitu/114510337278524055">Tikitu</a> for noticing that I accidentally edited out mentioning it. And thanks to <a href="https://hachyderm.io/@rituals/114513983150697363">Nathan</a> for catching my access-level mistake in an earlier version of this post. <a href="#fnref:tikitu" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ASCII]]></title>
    <link href="https://robnapier.net/ascii"/>
    <updated>2024-05-18T14:30:00-04:00</updated>
    <id>https://robnapier.net/ascii</id>
    <content type="html"><![CDATA[<p><em>Every part of this post is over-simplified. History is messy and difficult to sum up. The original version was twice as long and still over-simplified. Just go with it.</em></p>

<figure>
    <img src="https://robnapier.net/images/ascii/USASCII_code_chart.png" width="50%" alt="ASCII chart with 8 sticks (i.e. columns) and 16 rows, demonstrating the underlying structure of ASCII" />
    <figcaption>Public Domain. Source: <a href="https://commons.wikimedia.org/wiki/File:USASCII_code_chart.png">WikiCommons</a></figcaption>
</figure>

<p>In 1961 the American Standards Association began developing a new character encoding to replace the dozens of existing systems. In the end they created the 7-bit system that we call the <em>American Standard Code for Information Interchange</em>. We take ASCII for granted today, almost obvious, but it’s actually very carefully designed and surprisingly clever. ASCII is inspired by automated telegraph codes that evolved to drive teletypes.</p>

<!-- more -->

<p>To simplify hardware implementations, ASCII splits the characters into 8 vertical “sticks,” or columns, based on the first three bits of its encoding. The first two sticks are control characters which are intended to interact with the teletype itself. Things like starting a record or moving the carriage head. And that means, in hardware, you can look at just those first two bits and decide where to route the rest of the information for decoding. Very fast. Very easy to implement.</p>

<p>In stick 3 (0x30-0x3F) come the digits zero through nine. That means you can just stick a “3” on the front of any digit and you get the character for that digit. That’s not an accident. Notice how uppercase and lowercase letters differ by just one bit. Makes case-insensitive search really easy, just clear one bit. Also not an accident.</p>

<h2 id="before-ascii-ebcdic">Before ASCII: (E)BCDIC</h2>

<figure>
    <img src="https://robnapier.net/images/ascii/codes-07.gif" width="50%" alt="EBCDIC chart, showing structure of EBCDIC, specifically the many blank areas of unassigned codepoints" />
    <figcaption>CC BY-SA. Source: <a href="https://en.wikipedia.org/wiki/EBCDIC">Wikipedia:EBCDIC</a></figcaption>
</figure>

<p>IBM, who didn’t invent ASCII but was part of the committee, had decades of experience evolving what eventually became their 8-bit EBCDIC, <em>Extended Binary Coded Decimal Interchange Code</em>. In EBCDIC, the decimal digits start at 0xF0 rather than 0x30, but the concept is the same.</p>

<figure class="embed-right">
    <img src="https://robnapier.net/images/ascii/Blue-punch-card-front.png" width="50%" alt="IBM punch card, showing the layout of the card" />
    <figcaption>IBM-style punch card, encoding the EBCDIC character set. Public Domain. Source: <a href="https://commons.wikimedia.org/wiki/File:Blue-punch-card-front.png">WikiCommons</a></figcaption>
</figure>

<p>As the name suggests, it extends the previous 6-bit BCDIC format, which was designed to work with punch card equipment and mechanical tabulators, which is why it has what seem like odd “gaps” in its layout. This approach made it more compatible with the existing 6-bit systems and the related equipment. It isn’t particularly well-suited to electrical or magnetic encoding, but it taught IBM the value of lining up digits this way for BCD conversions.<sup id="fnref:holes"><a href="#fn:holes" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<p>If you’re working on business-focused computers, rather than scientific computing, the math generally isn’t very complicated. There aren’t a lot of square roots or logarithms in accounting. You mostly need add, subtract, multiply, and the occasional divide. But you spend a lot of time inputting and outputting numeric results in base 10. So it makes sense to do all your math in decimal so that converting back and forth between digits and their characters is really cheap and you avoid <a href="https://floating-point-gui.de">base-conversion rounding errors</a>. And that’s exactly what they did. A lot of IBM computers did all their math in binary coded decimal, and (E)BCDIC and ASCII reflect that.</p>

<h2 id="math">Math!</h2>

<p>Now at the same time, there were completely different computers being built for scientific and engineering computing. While a lot of business computers used 6-, 8-, or 9-bit characters, or “bytes,” scientific computers often worked with 36-bit “words.” They did their math in binary because it’s more efficient. It made it more expensive to convert between numbers and characters for I/O, but scientific computers do a lot more computing than they do I/O-ing.</p>

<h3 id="sidebar-its-always-the-system360-or-the-pdp-11">Sidebar: It’s always the System/360 or the PDP-11</h3>

<p><em>Wait, why 36 bits? Who does that?</em> Well, 36 binary digits gives the same accuracy as 10 decimal digits.</p>

<p><em>OK, why 10 decimal digits?</em> To match the accuracy of the mechanical calculators they competed against.</p>

<p>Notice the lack of powers of 2? Yeah, our obsession with powers of 2 came later.</p>

<p>And by “later,” I mean 1964 and the IBM System/360.</p>

<figure class="embed-right">
    <img src="https://robnapier.net/images/ascii/IBMS360.jpg" width="50%" alt="IBM System/360 mainframe computer." />
    <figcaption>IBM System/360 mainframe computer. Source: <a href="https://web.archive.org/web/20230405074032/https://www.ibm.com/ibm/history/ibm100/us/en/icons/system360/">IBM</a></figcaption>
</figure>

<p>So many things about modern computers can be traced to the System/360, but one of the most ubiquitous is it used 8-bit characters, and IBM was powerful enough to make that the norm that we use to this day. Before the System/360, “bytes” came in a variety of sizes. After the System/360, a byte was 8 bits.</p>

<p>Despite IBM being a massive supporter of ASCII, the System/360 used EBCDIC because it was more compatible with existing IBM peripherals. So it’s kind of a distraction on our discussion of ASCII, but it’ll come back up later. History isn’t always a simple matter of “this caused that.” Sometimes a lot of things are going on at the same time. EBCDIC technically <strong>post-dates</strong> ASCII by a few months. Sometimes history doesn’t quite follow the narrative.</p>

<h2 id="the-many-sciis">The many *SCIIs</h2>

<figure>
    <img src="https://robnapier.net/images/ascii/ISO646.png" alt="ISO 646 chart, showing some of the many national variants of ASCII." />
    <figcaption>Some of the many ISO 646 national variants. CC BY-SA. Source: <a href="https://en.wikipedia.org/wiki/ISO/IEC_646#ISO/IEC_646_national_variants">Wikipedia:ISO/IEC 646</a></figcaption>
</figure>

<p>Getting back to 7-bit ASCII. ASCII was pretty clever, but it’s also very US-centric. That wasn’t because no one was thinking about other countries and cultures. ASCII is the <strong>American</strong> Standard Code. It is just one of numerous national standards under the ISO/IEC 646 umbrella. For example, there’s YUSCII, the Yugoslav Standard Code. There’s a Chinese national standard, an Icelandic standard, two Japanese, a couple of Canadian. There’s a ton of them.</p>

<figure>
    <img src="https://robnapier.net/images/ascii/ISOIEC-646-INV.png" width="50%" alt="ISO 646 chart, showing the invariant characters in white and the customizable characters in gray." />
    <figcaption>ISO/IEC 646 chart with national variants and diacritics indicated. CC BY-SA. Source: <a href="https://en.wikipedia.org/wiki/ISO/IEC_646#Code_page_layout">Wikipedia:ISO/IEC 646</a></figcaption>
</figure>

<p>The idea was that there were certain invariant characters across standards, the ones in white, and then countries could assign whatever they wanted to certain code points, the ones in gray. And they could get combining characters using a backspace with diacritics. But you’ll notice there are only 9 customizable characters. Not a lot to work with. And building accented characters with backspace makes many text algorithms very hard.</p>

<p>But after the System/360 (I told you it’d come back up), more computers moved to 8-bit characters. And with the rise of microcomputers, most of which were 8-bit, there was this extra bit to work with. Some systems used the extra bit to carry extra information, or used it as a parity bit to detect data corruption. But it could also be used to get another 128 characters. That’s a lot, but it’s still nowhere close to enough to cover everything you’d want, even just for Latin-based writing systems.</p>

<p>So all those ISO/IEC 646 national standards morphed into a menagerie of ISO/IEC 8859 “extended ASCII” encodings, establishing the American national standard as the base that others built on, and thankfully getting rid of the “backspace for diacritics” system. The most popular was Latin-1, based mostly on an older DEC standard called the Multinational Character Set. It does a pretty good job of covering Western European languages, along with several others.</p>

<figure>
    <img src="https://robnapier.net/images/ascii/Latin-1.png" width="50%" alt="ISO 8859-1 chart, showing the characters in the Latin-1 encoding." />
    <figcaption>ISO 8859-1 chart. CC BY-SA. Source: <a href="https://en.wikipedia.org/wiki/ISO/IEC_8859-1#Code_page_layout">Wikipedia:ISO/IEC 8859-1</a></figcaption>
</figure>

<p>But on the other hand, consider:</p>

<ul>
  <li>Język Polski (Polish)</li>
  <li>Latviešu Valoda (Latvian)</li>
  <li>Hànyǔ Pīnyīn (Chinese Pinyin)</li>
</ul>

<p>They’re all “Latin-based,” but they all need characters, mostly in the form of diacritics or tone marks, that aren’t in Latin-1. And if you like diacritics <strong>and</strong> tone marks on your Latin, you can have that, too:</p>

<ul>
  <li>Tiếng Việt (Vietnamese)</li>
</ul>

<p>Oh dear….</p>

<p>So Latin-1 only does a “pretty good job” for Western European languages, but there are still a lot more languages out there using Latin that need their own extended ASCII. Non-Latin alphabets like Cyrillic, Greek, Arabic, Hebrew, and Thai are all encoded using different forms of extended ASCII, too. Even Asian-language encodings like Big5 and Shift JIS are based on ASCII, or at least compatible with it. The number 65 is the encoding of the uppercase Latin A almost everywhere, even in non-Latin encodings. Not an accident.</p>

<p>But this consistency can also be a problem. The encodings are “almost compatible.” They’re so compatible that it is very difficult to look at an arbitrary text file and determine what encoding it’s in. Extended ASCII is also very “dense.” Every possible sequence of bytes is a valid extended ASCII string. If you encounter the string “Tiêìng Viêòt”, have you accidentally treated the CP1258 encoding of “Tiếng Việt” as if it were Latin-1? Or is this text intentional, like it is in this document?</p>

<p>Even worse, there’s no easy way to mix encodings in the same document. Even if you add markup to indicate the encoding of each section, algorithms like searching becomes incredibly hard. And if you jump into the middle of a document, or worse, a stream, you have to rewind to find out what the current encoding is.</p>

<p>It’s…bad.</p>

<h2 id="what-if-we-unified-all-of-this-">What if we “unified” all of this? 🤔</h2>

<p>It took a few decades to finally build a better way. But that’s for another post.</p>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:holes">
      <p>I’m familiar with the common story that says that EBCDIC is laid out the way it is to minimize sequential holes in order to prevent weakening the card. I can’t find any primary source for that, and it doesn’t really follow from the character layout. The only evidence I’ve seen given is the slightly surprising placement of the ‘S’ encoding. But I expect that this was more about placing the ‘/’ encoding near the numbers in the older 6-bit encodings (the ones where the letters are “backwards”). Just modifying the ‘S’ encoding slightly shouldn’t have much if any impact on tape or card integrity. If the goal were to manage where holes show up, I would expect the letters to be laid out based on some English-frequency basis, or scattered around the encoding table, not laid out compactly and alphabetically. I’ve been reading <a href="https://archive.org/details/mackenzie-coded-char-sets/">Coded Character Sets, History and Development</a>, published in 1980, and I can’t find any mention of BCD encodings trying to optimize hole placement. <a href="#fnref:holes" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[AnyCodingKey]]></title>
    <link href="https://robnapier.net/anycodingkey"/>
    <updated>2024-05-04T16:37:00-04:00</updated>
    <id>https://robnapier.net/anycodingkey</id>
    <content type="html"><![CDATA[<p>Let’s talk about CodingKey. It’s a protocol. It is not a magic enum thing. Coding keys do not have to be enums. There is some special compiler magic for when CodingKeys are enums, but it’s just a protocol.</p>

<p>It’s something that wraps a string value, that may also wrap an int value. That’s it.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">protocol</span> <span class="kt">CodingKey</span> <span class="p">:</span> <span class="kt">CustomDebugStringConvertible</span><span class="p">,</span> <span class="kt">CustomStringConvertible</span><span class="p">,</span> <span class="kt">Sendable</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">stringValue</span><span class="p">:</span> <span class="kt">String</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
    <span class="nf">init</span><span class="p">?(</span><span class="nv">stringValue</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span>
    <span class="k">var</span> <span class="nv">intValue</span><span class="p">:</span> <span class="kt">Int</span><span class="p">?</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
    <span class="nf">init</span><span class="p">?(</span><span class="nv">intValue</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>
<!-- more -->

<p>You can see how the compiler generates automatic coding keys by running it through <code class="language-plaintext highlighter-rouge">swiftc -print-ast</code>. That will output the Abstract Syntax Tree as Swift code, after automatic conformances are injected.</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>% <span class="nb">echo</span> <span class="s1">'struct Person:Decodable { var name: String }'</span> | swiftc <span class="nt">-print-ast</span> -
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Output of `-print-ast`</span>
<span class="kd">internal</span> <span class="kd">struct</span> <span class="kt">Person</span> <span class="p">:</span> <span class="kt">Decodable</span> <span class="p">{</span>
  <span class="kd">internal</span> <span class="k">var</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span>
  <span class="kd">private</span> <span class="kd">enum</span> <span class="kt">CodingKeys</span> <span class="p">:</span> <span class="kt">CodingKey</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">name</span>
    <span class="kd">@_implements</span><span class="p">(</span><span class="kt">Equatable</span><span class="p">,</span> <span class="o">==</span><span class="p">(</span><span class="nv">_</span><span class="p">:</span><span class="nv">_</span><span class="p">:))</span> <span class="kd">fileprivate</span> <span class="kd">static</span> <span class="kd">func</span> <span class="nf">__derived_enum_equals</span><span class="p">(</span><span class="n">_</span> <span class="nv">a</span><span class="p">:</span> <span class="kt">Person</span><span class="o">.</span><span class="kt">CodingKeys</span><span class="p">,</span> <span class="n">_</span> <span class="nv">b</span><span class="p">:</span> <span class="kt">Person</span><span class="o">.</span><span class="kt">CodingKeys</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Bool</span> <span class="p">{</span>
      <span class="kd">private</span> <span class="k">var</span> <span class="nv">index_a</span><span class="p">:</span> <span class="kt">Int</span>
      <span class="k">switch</span> <span class="n">a</span> <span class="p">{</span>
      <span class="k">case</span> <span class="o">.</span><span class="nv">name</span><span class="p">:</span>
        <span class="n">index_a</span> <span class="o">=</span> <span class="mi">0</span>
      <span class="p">}</span>
      <span class="kd">private</span> <span class="k">var</span> <span class="nv">index_b</span><span class="p">:</span> <span class="kt">Int</span>
      <span class="k">switch</span> <span class="n">b</span> <span class="p">{</span>
      <span class="k">case</span> <span class="o">.</span><span class="nv">name</span><span class="p">:</span>
        <span class="n">index_b</span> <span class="o">=</span> <span class="mi">0</span>
      <span class="p">}</span>
      <span class="k">return</span> <span class="n">index_a</span> <span class="o">==</span> <span class="n">index_b</span>
    <span class="p">}</span>
    <span class="kd">fileprivate</span> <span class="kd">func</span> <span class="nf">hash</span><span class="p">(</span><span class="n">into</span> <span class="nv">hasher</span><span class="p">:</span> <span class="k">inout</span> <span class="kt">Hasher</span><span class="p">)</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
    <span class="o">...</span>
<span class="p">}</span>
</code></pre></div></div>

<p>It’ll generate an enum, and a few dozen or a few hundred lines worth of conformances. You’ll notice that Equatable implementation is based on a switch statement and numeric values rather than the string comparison you might have expected. Comparing integers is a lot faster than strings.</p>

<p>But the important part is that it generates a very simple <code class="language-plaintext highlighter-rouge">stringValue</code> initializer and property. For int values, it just returns nil. It doesn’t support int values.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="nf">init</span><span class="p">?(</span><span class="nv">stringValue</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">switch</span> <span class="n">stringValue</span> <span class="p">{</span>
  <span class="k">case</span> <span class="s">"name"</span><span class="p">:</span>
    <span class="k">self</span> <span class="o">=</span> <span class="kt">Person</span><span class="o">.</span><span class="kt">CodingKeys</span><span class="o">.</span><span class="n">name</span>
  <span class="k">default</span><span class="p">:</span>
    <span class="k">return</span> <span class="kc">nil</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">private</span> <span class="nf">init</span><span class="p">?(</span><span class="nv">intValue</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="kc">nil</span>
<span class="p">}</span>

<span class="kd">fileprivate</span> <span class="k">var</span> <span class="nv">intValue</span><span class="p">:</span> <span class="kt">Int</span><span class="p">?</span> <span class="p">{</span>
  <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">nil</span> <span class="p">}</span>
<span class="p">}</span>

<span class="kd">fileprivate</span> <span class="k">var</span> <span class="nv">stringValue</span><span class="p">:</span> <span class="kt">String</span> <span class="p">{</span>
  <span class="k">get</span> <span class="p">{</span>
    <span class="k">switch</span> <span class="k">self</span> <span class="p">{</span>
    <span class="k">case</span> <span class="o">.</span><span class="nv">name</span><span class="p">:</span>
      <span class="k">return</span> <span class="s">"name"</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>What if we made a struct that did the same thing? Glad you asked:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">struct</span> <span class="kt">AnyCodingKey</span><span class="p">:</span> <span class="kt">CodingKey</span> <span class="p">{</span>
    <span class="kd">public</span> <span class="k">let</span> <span class="nv">stringValue</span><span class="p">:</span> <span class="kt">String</span>

    <span class="kd">public</span> <span class="k">var</span> <span class="nv">intValue</span><span class="p">:</span> <span class="kt">Int</span><span class="p">?</span>

    <span class="kd">public</span> <span class="nf">init</span><span class="p">(</span><span class="nv">stringValue</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">stringValue</span> <span class="o">=</span> <span class="n">stringValue</span>
    <span class="p">}</span>

    <span class="kd">public</span> <span class="nf">init</span><span class="p">?(</span><span class="nv">intValue</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">nil</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This is my absolute favorite custom type and I use it all the time. This is its most minimal form, and the way you’ll see it pretty often in the wild. Lots of people have invented this under different names.</p>

<p>The form I use is a <a href="https://github.com/rnapier/advanced-codable/blob/26a4b09c7647b169289512aa877f7e118b6442cc/Codable.playground/Pages/Defaulting.xcplaygroundpage/Contents.swift#L19-L35">little more fancy</a>. It supports Int keys, and most importantly it conforms to ExpressibleByStringLiteral so that I can use quoted strings as keys. But at its heart, it’s just this, a coding key that can wrap any String and so can be the key of any JSON object.</p>

<p>Why do I love this struct so much? Well, for one, it gets rid of the need for defining CodingKeys.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">Person</span><span class="p">:</span> <span class="kt">Decodable</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span>
    <span class="k">var</span> <span class="nv">age</span><span class="p">:</span> <span class="kt">Int</span>
    <span class="k">var</span> <span class="nv">children</span><span class="p">:</span> <span class="p">[</span><span class="kt">Person</span><span class="p">]?</span>
<span class="p">}</span>

<span class="nf">init</span><span class="p">(</span><span class="n">from</span> <span class="nv">decoder</span><span class="p">:</span> <span class="kt">Decoder</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">c</span> <span class="o">=</span> <span class="k">try</span> <span class="n">decoder</span><span class="o">.</span><span class="nf">container</span><span class="p">(</span><span class="nv">keyedBy</span><span class="p">:</span> <span class="kt">AnyCodingKey</span><span class="o">.</span><span class="k">self</span><span class="p">)</span>

    <span class="n">name</span>     <span class="o">=</span> <span class="k">try</span> <span class="n">c</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">String</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">forKey</span><span class="p">:</span> <span class="s">"name"</span><span class="p">)</span>
    <span class="n">age</span>      <span class="o">=</span> <span class="k">try</span> <span class="n">c</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">Int</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">forKey</span><span class="p">:</span> <span class="s">"age"</span><span class="p">)</span>
    <span class="n">children</span> <span class="o">=</span> <span class="k">try</span> <span class="n">c</span><span class="o">.</span><span class="nf">decodeIfPresent</span><span class="p">([</span><span class="kt">Person</span><span class="p">]</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">forKey</span><span class="p">:</span> <span class="s">"children"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The hard-coded string literals may cause you to freak out a little. But here’s the thing. If you’re only implementing Decodable or only implementing Encodable, that string will occur in exactly one place which is exactly the place you use it. That’s better than creating a hand-written constant somewhere else. And I generally recommend that you only implement Encodable or Decodable unless you need them both. Unneeded conformances just add headaches and overhead.</p>

<p>And with this tool some really interesting, and ultimately quite simple, syntax is possible.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">Decoder</span> <span class="p">{</span>
    <span class="kd">public</span> <span class="kd">func</span> <span class="nf">anyKeyedContainer</span><span class="p">()</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">KeyedDecodingContainer</span><span class="o">&lt;</span><span class="kt">AnyCodingKey</span><span class="o">&gt;</span> <span class="p">{</span>
        <span class="k">try</span> <span class="nf">container</span><span class="p">(</span><span class="nv">keyedBy</span><span class="p">:</span> <span class="kt">AnyCodingKey</span><span class="o">.</span><span class="k">self</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">KeyedDecodingContainer</span> <span class="p">{</span>
    <span class="kd">public</span> <span class="kd">subscript</span><span class="o">&lt;</span><span class="kt">T</span><span class="p">:</span> <span class="kt">Decodable</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">key</span><span class="p">:</span> <span class="kt">Key</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">T</span> <span class="p">{</span>
        <span class="k">get</span> <span class="k">throws</span> <span class="p">{</span> <span class="k">try</span> <span class="k">self</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">T</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">forKey</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>
    <span class="p">}</span>
    <span class="kd">public</span> <span class="kd">subscript</span><span class="o">&lt;</span><span class="kt">T</span><span class="p">:</span> <span class="kt">Decodable</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ifPresent</span> <span class="nv">key</span><span class="p">:</span> <span class="kt">Key</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">T</span><span class="p">?</span> <span class="p">{</span>
        <span class="k">get</span> <span class="k">throws</span> <span class="p">{</span> <span class="k">try</span> <span class="k">self</span><span class="o">.</span><span class="nf">decodeIfPresent</span><span class="p">(</span><span class="kt">T</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">forKey</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And now, custom decoding looks like this:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">init</span><span class="p">(</span><span class="n">from</span> <span class="nv">decoder</span><span class="p">:</span> <span class="kt">Decoder</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">c</span> <span class="o">=</span> <span class="k">try</span> <span class="n">decoder</span><span class="o">.</span><span class="nf">anyKeyedContainer</span><span class="p">()</span>
    <span class="n">name</span>     <span class="o">=</span> <span class="k">try</span> <span class="n">c</span><span class="p">[</span><span class="s">"name"</span><span class="p">]</span>
    <span class="n">age</span>      <span class="o">=</span> <span class="k">try</span> <span class="n">c</span><span class="p">[</span><span class="s">"age"</span><span class="p">]</span>
    <span class="n">children</span> <span class="o">=</span> <span class="k">try</span> <span class="n">c</span><span class="p">[</span><span class="nv">ifPresent</span><span class="p">:</span> <span class="s">"children"</span><span class="p">]</span>
<span class="p">}</span>
</code></pre></div></div>

<p>See my <a href="https://github.com/rnapier/advanced-codable/blob/main/Codable.playground/Sources/Decoder%2BAnyCodingKey.swift">advanced-codable</a> repo for lots of examples that handle optionals, default values, robust error handling, and more. But the point isn’t to build a fancy library. The point is that with just a few lines of code, you can implement the things you need for your specific problem. And that the starting point is AnyCodingKey.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Littlest Type]]></title>
    <link href="https://robnapier.net/never"/>
    <updated>2019-10-28T13:02:00-04:00</updated>
    <id>https://robnapier.net/never</id>
    <content type="html"><![CDATA[<p>Sometimes there’s code so commonplace that we forget how strange it actually is. I mean, Swift is a strongly typed language right? Types types types! We say what things are, and the compiler enforces it for us. But then you see some piece of code like this:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">addOne</span><span class="p">(</span><span class="n">_</span> <span class="nv">x</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Int</span> <span class="p">{</span>
    <span class="nf">fatalError</span><span class="p">(</span><span class="s">"Haha! No Int for you!"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>That’s legal Swift. I don’t think many would find that surprising. Of course that’s legal, right? But it <em>is</em> surprising. <code class="language-plaintext highlighter-rouge">addOne</code> claims to be a function that accepts an Int and returns an Int. It does accept an Int, but…<em>it doesn’t return an Int</em>.</p>

<p>“Don’t be silly, Rob. It crashes. It can’t return an Int if it crashes.”</p>

<p>Well, yeah. But it promised to return an Int. It didn’t promise to “return an Int or crash,” did it? The whole point of strong types was that the compiler would enforce our promises, and the compiler doesn’t bat an eye at this code.</p>

<p>“The compiler can’t possibly know everything that might crash.”</p>

<p>I’m not ready to concede that, but even so, the compiler clearly can see that this function doesn’t return an Int. There’s no <code class="language-plaintext highlighter-rouge">return intValue</code> anywhere. This should prick our ears a bit. Something is strange here. Is it just compiler magic, or is there something deeper?</p>

<p>Hint: There’s something deeper.
<!-- more --></p>

<h3 id="staring-into-the-void">Staring into the Void</h3>

<p>Let’s take a step back and think about another thing that should surprise us.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">printSquid</span><span class="p">:</span> <span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Void</span> <span class="o">=</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🦑"</span><span class="p">)</span> <span class="p">}</span>
</code></pre></div></div>

<p>So, <code class="language-plaintext highlighter-rouge">printSquid</code> is a closure that takes no parameters and returns…what?</p>

<p>You might be tempted to say “nothing.” But that’s not what the code says. It says it returns Void. What’s Void?</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">typealias</span> <span class="kt">Void</span> <span class="o">=</span> <span class="p">()</span>
</code></pre></div></div>

<p>Void is a real thing. It’s the type of the empty tuple. It’s not “nothing.” In Swift, the type <code class="language-plaintext highlighter-rouge">()</code> and the value <code class="language-plaintext highlighter-rouge">()</code> happen to have the same spelling. When we mean <code class="language-plaintext highlighter-rouge">()</code> as a return type, we traditionally write it using the typealias Void. But <code class="language-plaintext highlighter-rouge">() -&gt; ()</code> is exactly the same thing as <code class="language-plaintext highlighter-rouge">() -&gt; Void</code>. Why “Void?” Because Swift has ObjC roots, and ObjC is C-like, and in C there are <code class="language-plaintext highlighter-rouge">void</code> functions that literally return nothing.</p>

<p>In Swift, every function returns something. There are functions that return <code class="language-plaintext highlighter-rouge">()</code>, and there’s some syntactic sugar that inserts <code class="language-plaintext highlighter-rouge">-&gt; Void</code> and <code class="language-plaintext highlighter-rouge">return ()</code> for you in some cases. But you’re free to include them if you like (it’s not particularly idiomatic Swift, but it’s legal).</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">f</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Void</span> <span class="p">{}</span>
<span class="kd">func</span> <span class="nf">g</span><span class="p">()</span> <span class="p">{</span> <span class="nf">return</span> <span class="p">()</span> <span class="p">}</span>
</code></pre></div></div>

<p>And functions like <code class="language-plaintext highlighter-rouge">print</code> that seem to have no return value, really do return Void:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">printResult</span><span class="p">:</span> <span class="kt">Void</span> <span class="o">=</span> <span class="nf">print</span><span class="p">(</span><span class="s">"🦑"</span><span class="p">)</span> <span class="c1">// 🦑</span>
<span class="nf">print</span><span class="p">(</span><span class="n">printResult</span><span class="p">)</span>                  <span class="c1">// ()</span>
</code></pre></div></div>

<p>If we don’t add the <code class="language-plaintext highlighter-rouge">: Void</code> here, the compiler will emit a warning because you usually don’t want Void values, but they’re totally legal.</p>

<h3 id="the-measure-of-a-type">The measure of a type</h3>

<p>Each type has a set of values that are part of that type. Some types have an enormous number of values. Int has around 18 quintillion values. String has even more. And some types have very few values. Most enums have just a handful of possible values. Bool has just 2. A lot of the power of strong types is that we can create <em>small</em> types; types that can only hold exactly the values that are legal for our program. That’s why we prefer enums to String and Int unless we mean “arbitrary text” or “an arbitrary number,” and we prefer structs to Dictionary unless we mean “an arbitrary mapping of keys to values.” Smaller, more constrained types help the compiler help us.</p>

<p>So how small can a type get?</p>

<p>Void has just one value. So that’s pretty small. In most languages that have this type, it’s called Unit. The one-value type.</p>

<p>Can they get smaller?</p>

<h3 id="not-a-value-in-sight">Not a value in sight</h3>

<p>It’s time to get back to the original example:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">addOne</span><span class="p">(</span><span class="n">_</span> <span class="nv">x</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Int</span> <span class="p">{</span>
    <span class="nf">fatalError</span><span class="p">(</span><span class="s">"Haha! No Int for you!"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Looking at <code class="language-plaintext highlighter-rouge">fatalError</code>, it feels a lot like <code class="language-plaintext highlighter-rouge">print</code>. The syntax is similar. But we can’t just throw <code class="language-plaintext highlighter-rouge">print</code> into places <code class="language-plaintext highlighter-rouge">fatalError</code> goes:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">addOne</span><span class="p">(</span><span class="n">_</span> <span class="nv">x</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Int</span> <span class="p">{</span>
    <span class="nf">print</span><span class="p">(</span><span class="s">"Haha! No Int for you!"</span><span class="p">)</span> <span class="c1">// Cannot convert return expression of type '()' to return type 'Int'</span>
    <span class="o">^^^^^</span>
<span class="p">}</span>
</code></pre></div></div>

<p>How does the compiler know we’re allowed to use <code class="language-plaintext highlighter-rouge">fatalError</code> here, but not <code class="language-plaintext highlighter-rouge">print</code>? Maybe the compiler just knows that <code class="language-plaintext highlighter-rouge">fatalError</code> is special. That’s what was done prior to Swift 3:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">@noreturn</span> <span class="kd">public</span> <span class="kd">func</span> <span class="nf">fatalError</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="o">^^^^^^^^^</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">@noreturn</code> attribute told the compiler that this function doesn’t return, and then the compiler had logic to handle that case and let us skip returning the Int we promised. But…bleh. I hate that solution. It opens up weird corner cases. For example, what happens if we add <code class="language-plaintext highlighter-rouge">@noreturn</code> to a function that we claim does return something, or something that throws:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">@noreturn</span> <span class="kd">func</span> <span class="nf">addOne</span><span class="p">(</span><span class="n">_</span> <span class="nv">x</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Int</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
<span class="kd">@noreturn</span> <span class="kd">func</span> <span class="nf">runForever</span><span class="p">()</span> <span class="k">throws</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
</code></pre></div></div>

<p>The first one is probably an error, and maybe the compiler should forbid it. But what about the second one? Is throwing a “return?” At the implementation level, it actually is. But should this attribute allow it? There’s not a really obvious answer. Is it possible for a function to require a <code class="language-plaintext highlighter-rouge">@noreturn</code> parameter? How does this impact function overloading?</p>

<p>In Swift 3 they got rid of the attribute hack, and solved the problem with a type: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0102-noreturn-bottom-type.md">Never</a>. The signature of <code class="language-plaintext highlighter-rouge">fatalError</code> is now:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">func</span> <span class="nf">fatalError</span><span class="p">(</span><span class="o">...</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Never</span>
                               <span class="o">^^^^^</span>
</code></pre></div></div>

<p>So what’s Never? Is it some new compiler trick? Nope. It’s just a type, an enum with no cases:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">enum</span> <span class="kt">Never</span> <span class="p">{}</span>
</code></pre></div></div>

<p>How many Never values are there? Well, none. You can’t construct one. That has all kinds of interesting implications.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">f</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Never</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>   <span class="c1">// f never returns</span>
<span class="kd">func</span> <span class="nf">g</span><span class="p">(</span><span class="nv">_</span><span class="p">:</span> <span class="kt">Never</span><span class="p">)</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>    <span class="c1">// g can never be called</span>

<span class="kd">struct</span> <span class="kt">S</span> <span class="p">{</span>                  <span class="c1">// S can never be constructed</span>
    <span class="k">let</span> <span class="nv">nope</span><span class="p">:</span> <span class="kt">Never</span>
    <span class="o">...</span>
<span class="p">}</span> 

<span class="kd">enum</span> <span class="kt">E</span> <span class="p">{</span>
    <span class="k">case</span> <span class="nf">ok</span><span class="p">(</span><span class="kt">Int</span><span class="p">)</span>       <span class="c1">// E.ok can be constructed</span>
    <span class="k">case</span> <span class="nf">nope</span><span class="p">(</span><span class="kt">Never</span><span class="p">)</span>   <span class="c1">// E.nope can never be constructed</span>
<span class="p">}</span>

<span class="c1">// But also interesting:</span>

<span class="kd">struct</span> <span class="kt">G</span><span class="o">&lt;</span><span class="kt">Element</span><span class="o">&gt;</span> <span class="p">{}</span>
<span class="k">let</span> <span class="nv">ok</span> <span class="o">=</span> <span class="kt">G</span><span class="o">&lt;</span><span class="kt">Never</span><span class="o">&gt;</span><span class="p">()</span>     <span class="c1">// This is fine. Never can be a phantom type.</span>
</code></pre></div></div>

<p>Another interesting implication is that <code class="language-plaintext highlighter-rouge">[Never]</code> is <a href="https://twitter.com/cocoaphony/status/1184470123899478017">an empty array</a>.</p>

<p>Never is the smallest possible type. We call it an “uninhabited type.” There’s nothing special about the name “Never.” You can create your own no-case enum, and it’ll work the same.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Our own custom uninhabited type</span>
<span class="kd">enum</span> <span class="kt">NeverReturn</span> <span class="p">{}</span>

<span class="kd">func</span> <span class="nf">neverReturn</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">NeverReturn</span> <span class="p">{</span>
    <span class="c1">// We could call fatalError() here, since generating any uninhabited type</span>
    <span class="c1">// is sufficient to create any other. But we can also use an infinite loop.</span>
    <span class="c1">// The compiler can prove this will never return. Never isn't just for crashing!</span>
    <span class="k">while</span> <span class="kc">true</span> <span class="p">{}</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">addOne</span><span class="p">(</span><span class="n">_</span> <span class="nv">x</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Int</span> <span class="p">{</span>
    <span class="nf">neverReturn</span><span class="p">()</span>   <span class="c1">// It's fine not to return Int, because the compiler knows this doesn't return</span>
<span class="p">}</span>

<span class="c1">// While Never can be used to create a NeverReturn, they're not the same type</span>
<span class="k">let</span> <span class="nv">never</span><span class="p">:</span> <span class="kt">Never</span> <span class="o">=</span> <span class="nf">neverReturn</span><span class="p">()</span>           <span class="c1">// Cannot convert value of type 'NeverReturn' to specified type 'Never'</span>
<span class="k">let</span> <span class="nv">neverEver</span><span class="p">:</span> <span class="kt">NeverReturn</span> <span class="o">=</span> <span class="nf">fatalError</span><span class="p">()</span>  <span class="c1">// Cannot convert value of type 'Never' to specified type 'NeverReturn'</span>
</code></pre></div></div>

<p>While it’s possible to create your own uninhabited types, I don’t really recommend it. The Swift team considered having different types for things like “exit” vs “abort” and intentionally chose not to. One uninhabited type is probably plenty. But it’s nice that it’s not some magical name.</p>

<h3 id="you-never-hit-bottom">You never hit bottom</h3>

<p>In type theory, an uninhabited type is often called a bottom type, and written as ⊥. A bottom type is a subtype of every other type. So Never would be an Int and a String and a UIViewController and every other type. The opposite is the top type (⊤), the supertype of every other type. In Swift, that’s Any.</p>

<p>But in Swift, Never isn’t actually a bottom type. If it were, you could write this, and you can’t:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">x</span><span class="p">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="nf">fatalError</span><span class="p">()</span>   <span class="c1">// Cannot convert value of type 'Never' to specified type 'Int'</span>
</code></pre></div></div>

<p>It’s easy to fix this with a little extra syntax if you need it:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">x</span><span class="p">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="p">{</span> <span class="nf">fatalError</span><span class="p">()</span> <span class="p">}()</span> 
</code></pre></div></div>

<p>So Never acts like a bottom type when it’s being returned from a function, but not when it’s being passed to a function or assigned to a variable. It would be more consistent for Never to be a true bottom type, and for it to conform to every non-static protocol (i.e. protocols without static or init requirements). Whether that’s worth the weird corner cases it might create, I’m not sure. But maybe.</p>

<h3 id="some-things-just-dont-happen">Some things just don’t happen</h3>

<p>Never is my favorite type in stdlib. It’s been my favorite type since it was introduced in Swift 3, and the Combine framework has completely justified my love of it by applying it to generics.</p>

<p>Publishers generate a series of values or a typed failure:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">protocol</span> <span class="kt">Publisher</span> <span class="p">{</span>
    <span class="kd">associatedtype</span> <span class="kt">Output</span>
    <span class="kd">associatedtype</span> <span class="kt">Failure</span> <span class="p">:</span> <span class="kt">Error</span>
    <span class="kd">func</span> <span class="n">receive</span><span class="o">&lt;</span><span class="kt">S</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">subscriber</span><span class="p">:</span> <span class="kt">S</span><span class="p">)</span> <span class="k">where</span> <span class="kt">S</span> <span class="p">:</span> <span class="kt">Subscriber</span><span class="p">,</span> <span class="k">Self</span><span class="o">.</span><span class="kt">Failure</span> <span class="o">==</span> <span class="kt">S</span><span class="o">.</span><span class="kt">Failure</span><span class="p">,</span> <span class="k">Self</span><span class="o">.</span><span class="kt">Output</span> <span class="o">==</span> <span class="kt">S</span><span class="o">.</span><span class="kt">Input</span>
<span class="p">}</span>
</code></pre></div></div>

<p>But what should Failure be if the Publisher <em>never</em> generates errors? Never, of course. No magic needed. It just works. What if it <em>only</em> can generate a Failure? Well, then Output is Never (see <a href="https://developer.apple.com/documentation/combine/publishers/ignoreoutput">IgnoreOutput</a>). When there’s a proper type, the special cases disappear, and it just works.</p>

<p>So Never has gone from a little-known type solving a little-known problem around <code class="language-plaintext highlighter-rouge">fatalError</code> to something Swift developers will probably use every day without even thinking about it. And that makes me very happy.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Protocols v: At Your Request]]></title>
    <link href="https://robnapier.net/at-your-request"/>
    <updated>2019-10-26T17:04:00-04:00</updated>
    <id>https://robnapier.net/at-your-request</id>
    <content type="html"><![CDATA[<p>So, back to our <a href="https://robnapier.net/start-with-a-protocol">APIClient</a>. When last <a href="https://robnapier.net/thats-not-a-number">I left off</a>, I had the following client code:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="kd">class</span> <span class="kt">APIClient</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">let</span> <span class="nv">shared</span> <span class="o">=</span> <span class="kt">APIClient</span><span class="p">()</span>
    <span class="k">let</span> <span class="nv">baseURL</span> <span class="o">=</span> <span class="kt">URL</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="s">"https://www.example.com"</span><span class="p">)</span><span class="o">!</span>
    <span class="k">let</span> <span class="nv">transport</span><span class="p">:</span> <span class="kt">Transport</span>

    <span class="nf">init</span><span class="p">(</span><span class="nv">transport</span><span class="p">:</span> <span class="kt">Transport</span> <span class="o">=</span> <span class="kt">URLSession</span><span class="o">.</span><span class="n">shared</span><span class="p">)</span> <span class="p">{</span> <span class="k">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="n">transport</span> <span class="p">}</span>

    <span class="c1">// Fetch any Fetchable type given an ID, and return it asynchronously</span>
    <span class="kd">func</span> <span class="n">fetch</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">:</span> <span class="kt">Fetchable</span><span class="o">&gt;</span><span class="p">(</span><span class="n">_</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">Model</span><span class="o">.</span><span class="kt">ID</span><span class="p">,</span>
                                 <span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// Construct the URLRequest</span>
        <span class="k">let</span> <span class="nv">url</span> <span class="o">=</span> <span class="n">baseURL</span>
            <span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="kt">Model</span><span class="o">.</span><span class="n">apiBase</span><span class="p">)</span>
            <span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="s">"</span><span class="se">\(</span><span class="n">id</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
        <span class="k">let</span> <span class="nv">urlRequest</span> <span class="o">=</span> <span class="kt">URLRequest</span><span class="p">(</span><span class="nv">url</span><span class="p">:</span> <span class="n">url</span><span class="p">)</span>

        <span class="c1">// Send it to the transport</span>
        <span class="n">transport</span><span class="o">.</span><span class="nf">send</span><span class="p">(</span><span class="nv">request</span><span class="p">:</span> <span class="n">urlRequest</span><span class="p">)</span> <span class="p">{</span> <span class="n">data</span> <span class="k">in</span>
            <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="kt">Result</span> <span class="p">{</span> <span class="k">try</span> <span class="kt">JSONDecoder</span><span class="p">()</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">Model</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">from</span><span class="p">:</span> <span class="n">data</span><span class="o">.</span><span class="nf">get</span><span class="p">())</span> <span class="p">}</span>
            <span class="nf">completion</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This <code class="language-plaintext highlighter-rouge">fetch</code> method is great for getting a model by ID, but I have other things I want to do. For example, I’d like to periodically POST to /keepalive and return if there’s an error. That’s really similar, but kind of different.
<!-- more --></p>

<pre style="float: left; width: 45%; min-width: 450px">
// GET /&lt;model&gt;/&lt;id&gt; -&gt; Model
func fetch&lt;Model: Fetchable&gt;(
    _ id: Model.ID,
    completion: @escaping (Result&lt;Model, Error&gt;) -&gt; Void)
{<span style="color: yellow;">
    let urlRequest = URLRequest(url: baseURL
        .appendingPathComponent(Model.apiBase)
        .appendingPathComponent(&quot;\(id)&quot;)
    )</span>

    transport.fetch(request: urlRequest) {<span style="color: cyan">
        data in
        completion(Result {
            let decoder = JSONDecoder()
            return try decoder.decode(
                Model.self,
                from: data.get())
        })</span>
    }
}
</pre>

<pre style="width: 45%;">
// POST /keepalive -&gt; Error?
func keepAlive(
    completion: @escaping (Error?) -&gt; Void)
{<span style="color: yellow;">
    var urlRequest = URLRequest(url: baseURL
        .appendingPathComponent("keepalive")
    )
    urlRequest.httpMethod = "POST"</span>

    transport.send(request: urlRequest) {<span style="color: cyan">
        switch $0 {
        case .success: completion(nil)
        case .failure(let error): 
             completion(error)
        }</span>
    }
}
</pre>

<div style="clear: both;"></div>

<p>Both basically follow this pattern of build an URL request, pass it to transport, and then deal with the result. I know it’s just one line that exactly duplicates, but the structure is still really similar, and it feels we could pull this apart. The problem is that <code class="language-plaintext highlighter-rouge">fetch</code> is doing too much.</p>

<p>So maybe we pull out the part that changes and call it Request. But what should Request be? So often, I see people jump to a PAT (protocol with associated type) like this:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// This is a bad idea</span>
<span class="kd">protocol</span> <span class="kt">Request</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">urlRequest</span><span class="p">:</span> <span class="kt">URLRequest</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
    <span class="kd">associatedtype</span> <span class="kt">Response</span>
    <span class="k">var</span> <span class="nv">completion</span><span class="p">:</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Response</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>So what’s the question we ask whenever we make a PAT? Would I ever want an array of these? I think we would definitely want an array of requests. A list of pending requests. Chaining requests together. Requests that should be retried. We definitely want an array of requests. This is a great example where someone might come along as say, if only we had <a href="https://robnapier.net/existential-spelling">generalized existentials</a> then everything would be wonderful. No. That wouldn’t fix anything. The problem is this treats a PAT like a generic, which isn’t the right way to think about it.</p>

<h3 id="pats-are-not-generic-protocols-or-at-least-not-in-the-way-youre-thinking">PATs are not “generic protocols” (or at least not in the way you’re thinking)</h3>

<p>Generics and PATs are very different things that solve very different problems. Generics are type-parameterization. That means that the types are being passed as parameters to the function. They’re passed at compile time, but they’re still passed by the caller. When you say <code class="language-plaintext highlighter-rouge">Array&lt;Int&gt;</code>, you, the caller, get to decide what kinds of elements Array holds. In <code class="language-plaintext highlighter-rouge">Array&lt;Int&gt;(repeating: 0, count: 10)
</code>, Int is just as much a parameter as 0 and 10. It’s just a different kind of parameter.</p>

<p>PATs aren’t like that. Their associated types are not parameters passed by the caller. They’re hooks provided by the implementor of the conforming type (or whoever wrote the conforming extension). When you conform a type to a PAT, you have to provide a mapping of stuff that algorithms need to stuff this type has. Collection requires an Index type in order to implement subscripts (among other things). Set says “here’s my Set.Index type that Collection algorithms should use when you need an Index type.” Array says “please use Int as my Index for those algorithms.” As the consumer of Set or Array, you can’t change those choices. You can’t say “I want an Array indexed by Character.” That’s not up to you. It’s not a type parameter.</p>

<p>The point of a PAT is to allow algorithms to use the type. If you’re thinking about storage (like putting things in an Array) rather than algorithms, you probably do not want a PAT.</p>

<h3 id="first-use-it-then-build-it">First use it, then build it</h3>

<p>Rather than focusing first on how to construct a Request, let’s focus on how we’d like to <em>use</em> one. I wish something would just know all the stuff I needed to send to the transport….</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">APIClient</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">send</span><span class="p">(</span><span class="n">_</span> <span class="nv">request</span><span class="p">:</span> <span class="kt">Request</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">transport</span><span class="o">.</span><span class="nf">send</span><span class="p">(</span><span class="nv">request</span><span class="p">:</span> <span class="n">request</span><span class="o">.</span><span class="n">urlRequest</span><span class="p">,</span>
                       <span class="nv">completion</span><span class="p">:</span> <span class="n">request</span><span class="o">.</span><span class="n">completion</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This is a kind of <a href="https://robnapier.net/functional-wish-fulfillment">“wish driven development.”</a> We “wish” there were some type that could handle the URLRequest and completion handler for us, we pretend it exists, write the code that uses it, and then make it a reality. And the reality couldn’t be simpler:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">Request</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">urlRequest</span><span class="p">:</span> <span class="kt">URLRequest</span>
    <span class="k">let</span> <span class="nv">completion</span><span class="p">:</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Data</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span>
<span class="p">}</span>
</code></pre></div></div>

<p>OK, that’s simple, but that’s still not quite what we want. There’s no model information in there. I want to create Requests that know about model types, like this:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">client</span><span class="o">.</span><span class="nf">send</span><span class="p">(</span><span class="kt">Request</span><span class="o">.</span><span class="nf">fetching</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="kt">User</span><span class="o">.</span><span class="kt">ID</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">completion</span><span class="p">:</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="nv">$0</span><span class="p">)}</span> <span class="p">))</span>
</code></pre></div></div>

<p>So I want to put User.ID into a system and get User back out in the completion handler, but the system (Request) only understands Data. That means we’re making a type eraser. We’re hiding a type (User) inside Request. How? With one of the simplest type erasers you can have: a generic function or closure. Basically, we just take <code class="language-plaintext highlighter-rouge">fetch</code> and wrap it into a closure. Here’s <code class="language-plaintext highlighter-rouge">fetch</code>:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">APIClient</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="n">fetch</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">:</span> <span class="kt">Fetchable</span><span class="o">&gt;</span><span class="p">(</span><span class="n">_</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">Model</span><span class="o">.</span><span class="kt">ID</span><span class="p">,</span>
                                 <span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// Construct the URLRequest</span>
        <span class="k">let</span> <span class="nv">url</span> <span class="o">=</span> <span class="n">baseURL</span>
            <span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="kt">Model</span><span class="o">.</span><span class="n">apiBase</span><span class="p">)</span>
            <span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="s">"</span><span class="se">\(</span><span class="n">id</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
        <span class="k">let</span> <span class="nv">urlRequest</span> <span class="o">=</span> <span class="kt">URLRequest</span><span class="p">(</span><span class="nv">url</span><span class="p">:</span> <span class="n">url</span><span class="p">)</span>

        <span class="c1">// Send it to the transport</span>
        <span class="n">transport</span><span class="o">.</span><span class="nf">send</span><span class="p">(</span><span class="nv">request</span><span class="p">:</span> <span class="n">urlRequest</span><span class="p">)</span> <span class="p">{</span> <span class="n">data</span> <span class="k">in</span>
            <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="kt">Result</span> <span class="p">{</span> <span class="k">try</span> <span class="kt">JSONDecoder</span><span class="p">()</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">Model</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">from</span><span class="p">:</span> <span class="n">data</span><span class="o">.</span><span class="nf">get</span><span class="p">())</span> <span class="p">}</span>
            <span class="nf">completion</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And here’s <code class="language-plaintext highlighter-rouge">fetching</code>:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">Request</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">baseURL</span><span class="p">:</span> <span class="kt">URL</span> <span class="p">{</span> <span class="kt">URL</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="s">"https://www.example.com"</span><span class="p">)</span><span class="o">!</span> <span class="p">}</span>

    <span class="c1">// GET /&lt;model&gt;/&lt;id&gt; -&gt; Model</span>
    <span class="kd">static</span> <span class="kd">func</span> <span class="n">fetching</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">:</span> <span class="kt">Fetchable</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="kt">Model</span><span class="o">.</span><span class="kt">ID</span><span class="p">,</span>
                                           <span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Request</span>
    <span class="p">{</span>
        <span class="c1">// Construct the URLRequest</span>
        <span class="k">let</span> <span class="nv">url</span> <span class="o">=</span> <span class="n">baseURL</span>
            <span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="kt">Model</span><span class="o">.</span><span class="n">apiBase</span><span class="p">)</span>
            <span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="s">"</span><span class="se">\(</span><span class="n">id</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
        <span class="k">let</span> <span class="nv">urlRequest</span> <span class="o">=</span> <span class="kt">URLRequest</span><span class="p">(</span><span class="nv">url</span><span class="p">:</span> <span class="n">url</span><span class="p">)</span>

        <span class="k">return</span> <span class="k">self</span><span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">urlRequest</span><span class="p">:</span> <span class="n">urlRequest</span><span class="p">)</span> <span class="p">{</span>  <span class="c1">// Here's the closure that hides (erases) Model</span>
            <span class="n">data</span> <span class="k">in</span>
            <span class="nf">completion</span><span class="p">(</span><span class="kt">Result</span> <span class="p">{</span>
                <span class="k">let</span> <span class="nv">decoder</span> <span class="o">=</span> <span class="kt">JSONDecoder</span><span class="p">()</span>
                <span class="k">return</span> <span class="k">try</span> <span class="n">decoder</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">Model</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">from</span><span class="p">:</span> <span class="n">data</span><span class="o">.</span><span class="nf">get</span><span class="p">())</span>
            <span class="p">})</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">fetching</code> is a generic method, but it returns a non-generic Request struct. This kind of generic-&gt;non-generic conversion is an incredibly powerful way to simplify your system and keep generics from spiraling out of control.</p>

<p>You may ask “why a static <code class="language-plaintext highlighter-rouge">fetching</code> method rather than creating an <code class="language-plaintext highlighter-rouge">init(fetching:completion)</code> extension” For this one, <code class="language-plaintext highlighter-rouge">init</code> would probably be fine, but as you think about other kinds of Requests, especially ones with no parameters, it would get messy. For example, it’s hard to build a nice <code class="language-plaintext highlighter-rouge">init</code> for /keepalive. (This isn’t a deep design point; it’s just a stylistic choice. You might prefer <code class="language-plaintext highlighter-rouge">init(keepAliveWithCompletion:)</code>, and that’s up to you.)</p>

<p>In any case, this is how I’d build the /keepalive handler:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">Request</span> <span class="p">{</span>
    <span class="c1">// POST /keepalive -&gt; Error?</span>
    <span class="kd">static</span> <span class="kd">func</span> <span class="nf">keepAlive</span><span class="p">(</span><span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Error</span><span class="p">?)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Request</span>
    <span class="p">{</span>
        <span class="k">var</span> <span class="nv">urlRequest</span> <span class="o">=</span> <span class="kt">URLRequest</span><span class="p">(</span><span class="nv">url</span><span class="p">:</span> <span class="n">baseURL</span>
            <span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="s">"keepalive"</span><span class="p">)</span>
        <span class="p">)</span>
        <span class="n">urlRequest</span><span class="o">.</span><span class="n">httpMethod</span> <span class="o">=</span> <span class="s">"POST"</span>

        <span class="k">return</span> <span class="k">self</span><span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">urlRequest</span><span class="p">:</span> <span class="n">urlRequest</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">switch</span> <span class="nv">$0</span> <span class="p">{</span>
            <span class="k">case</span> <span class="o">.</span><span class="nv">success</span><span class="p">:</span> <span class="nf">completion</span><span class="p">(</span><span class="kc">nil</span><span class="p">)</span>
            <span class="k">case</span> <span class="o">.</span><span class="nf">failure</span><span class="p">(</span><span class="k">let</span> <span class="nv">error</span><span class="p">):</span> <span class="nf">completion</span><span class="p">(</span><span class="n">error</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="wrapping-up-the-network-stack">Wrapping up the network stack</h2>

<p>This is the end of my discussion of this little network stack (though not the end of my discussion of generics). It’s not designed to be a “real” network stack. I don’t expect anyone to use this directly as described. I build stacks based on these principles all the time, but I’ve never had one look exactly like this. They’re each quite specialized to their particular API, and the particular needs of the app. The goal here wasn’t to create a general purpose library to solve all networking problems. The goal was to show how you would extract generic code tailored to a problem. Your API is probably different, and you’ll probably build your solution in a different way. Don’t feel you have to use a Transport and an APIClient and a Request. (Though maybe you should use Transport… :D)</p>

<p>If you want to build a general purpose library around this, I suggest you first build small, custom libraries around several APIs that are very different from each other. Then look for the abstractions. Abstracting too soon, before you really understand the problem, is the most common cause of generic headaches.</p>

<p>There is no such thing as “as generic as possible.” Generic code is abstraction, and abstraction is choices. Choosing to make things flexible in one direction often makes it harder to be flexible in another. I have a long list of code bases where we needed more flexibility, and the first step was to rip out all the “flexible” code that made the wrong assumptions about what kind of flexibility would be needed and was never actually used.</p>

<blockquote>
  <p>Write concrete code first. Then work out the generics.</p>
</blockquote>

<p>If you stick to that, it’ll probably work out ok.</p>

<p><a href="https://robnapier.net/assets/protocols/StartWithAProtocol.zip">Swift Playground</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Protocols IV: That's Not a Number]]></title>
    <link href="https://robnapier.net/thats-not-a-number"/>
    <updated>2019-05-27T00:00:00-04:00</updated>
    <id>https://robnapier.net/thats-not-a-number</id>
    <content type="html"><![CDATA[<p>So far in this series, I’ve <a href="https://robnapier.net/start-with-a-protocol">created a simple APIClient</a> that can fetch any Fetchable type and decode it from a specific API, and then <a href="https://robnapier.net/a-mockery-of-protocols">extracted a Transport protocol</a> to abstract away the network layer. In this part, I’ll reconsider the top of the stack, the models, and see if I can make those more flexible.
<!-- more --></p>

<p>The current models are User and Document:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">User</span><span class="p">:</span> <span class="kt">Codable</span><span class="p">,</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">Int</span>
    <span class="k">let</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">Document</span><span class="p">:</span> <span class="kt">Codable</span><span class="p">,</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">Int</span>
    <span class="k">let</span> <span class="nv">title</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>
</code></pre></div></div>

<p>But now the server API is changing. Document IDs will be Strings, not Ints. (True story.) But really, IDs never really <em>were</em> Ints. I mean, IDs aren’t <em>numbers</em>. What would it mean to add two IDs together? Or divide them? How can I pretend that an ID is a kind of number if most number-like operations would be nonsense? The current design allows me to pass document IDs when I mean user IDs. It even lets me pass random integers when I mean an ID. That can’t be right. IDs are their own thing. They want a type.</p>

<p>As usual, I’ll start very concretely with User and see if anything generic develops. The first step is to lift the ID into its own type.</p>

<style>
    .chl { color: yellow; } /* code highlight */
</style>

<pre>
struct User: Codable, Hashable {
    <span class="chl">struct ID: Codable, Hashable { 
        let value: Int 
    }
    let id: ID</span>
    let name: String
}
</pre>

<p>So now creating a User looks like this:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">user</span> <span class="o">=</span> <span class="kt">User</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="kt">User</span><span class="o">.</span><span class="kt">ID</span><span class="p">(</span><span class="nv">value</span><span class="p">:</span> <span class="mi">1</span><span class="p">),</span> <span class="nv">name</span><span class="p">:</span> <span class="s">"Alice"</span><span class="p">)</span>
</code></pre></div></div>

<p>That’s ok, but I don’t like the <code class="language-plaintext highlighter-rouge">value:</code> label. It violates one of the principles of the <a href="https://swift.org/documentation/api-design-guidelines/#argument-labels">API Design Guidelines</a>:</p>

<blockquote>
  <p>In initializers that perform value preserving type conversions, omit the first argument label, e.g. <code class="language-plaintext highlighter-rouge">Int64(someUInt32)</code>.</p>
</blockquote>

<p>To comply, I should I add another initializer.</p>

<pre>
struct User: Codable, Hashable {
    struct ID: Codable, Hashable { 
        let value: Int 
        <span class="chl">init(_ value: Int) { self.value = value }</span>
    }
    let id: ID
    let name: String
}

let user = User(id: <span class="chl">User.ID(1)</span>, name: "Alice")
</pre>

<p>Much better. Document will be almost exactly the same.</p>

<pre>
struct Document: Codable, Hashable {
    struct ID: Codable, Hashable {
        let value: <span class="chl">String</span>
        init(_ value: <span class="chl">String</span>) { self.value = value }
    }
    let id: ID
    let title: String
}
</pre>

<p>It’s not a lot of code, but anytime I’m tempted to cut and paste, it’s time to wonder if there’s generic code hiding in there. After all, most of the model types in this system will probably have an ID.</p>

<h2 id="maybe-a-protocol">Maybe a protocol?</h2>

<p>When I see code duplication, I often reach first for a protocol so I can extract a generic algorithm. That’s something protocols are very good at. In the case of ID, there are two duplicated concepts: identifiers conform to Codable and Hashable, and identifiers have a “no label” initializer.</p>

<p><span class="pullquote-right" data-pullquote="It&#8217;s important to focus on the duplication of concepts, not keystrokes.">
It’s important to focus on the duplication of concepts, not keystrokes. <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> doesn’t mean “never type the same letters twice.” The point is to extract things that will <em>vary together</em>. I don’t want to capture “types that include the characters <code class="language-plaintext highlighter-rouge">: Codable, Hashable</code> and <code class="language-plaintext highlighter-rouge">init(_...</code>.” I want to capture “things that behave as identifiers.” So I’m going to capture that concept as Identifier:
</span></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Identifier</span><span class="p">:</span> <span class="kt">Codable</span><span class="p">,</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="kd">associatedtype</span> <span class="kt">Value</span><span class="p">:</span> <span class="kt">Codable</span><span class="p">,</span> <span class="kt">Hashable</span>
    <span class="k">var</span> <span class="nv">value</span><span class="p">:</span> <span class="kt">Value</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
    <span class="nf">init</span><span class="p">(</span><span class="nv">value</span><span class="p">:</span> <span class="kt">Value</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">Identifier</span> <span class="p">{</span>
    <span class="nf">init</span><span class="p">(</span><span class="n">_</span> <span class="nv">value</span><span class="p">:</span> <span class="kt">Value</span><span class="p">)</span> <span class="p">{</span> <span class="k">self</span><span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="nv">value</span><span class="p">:</span> <span class="n">value</span><span class="p">)</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>With that, User.ID is simplified to:</p>

<pre>
struct User: Codable, Hashable {
    <span class="chl">struct ID: Identifier { let value: Int }</span>
    let id: ID
    let name: String
}
</pre>

<p>To use it, <code class="language-plaintext highlighter-rouge">APIClient.fetch</code> needs to accept an ID type rather than an Int:</p>

<pre>
func fetch&lt;Model: Fetchable&gt;(_ model: Model.Type, <span class="chl">id: Model.ID</span>,
                             completion: @escaping (Result&lt;Model, Error&gt;) -&gt; Void)
</pre>

<p>And of course Fetchable needs to add an ID type:</p>

<pre>
protocol Fetchable: Decodable {
    <span class="chl">associatedtype ID: Identifier</span>
    static var apiBase: String { get }  // The part of the URL for this fetchable type
}
</pre>

<p>Wait a minute… There’s nothing “of course” about that last change. Fetchable used to be a simple protocol. Now it’s a PAT (protocol with associated type). That’s a big change in Swift. Whenever you find yourself typing <code class="language-plaintext highlighter-rouge">associatedtype</code>, you need to stop for a moment and think “would I ever want to put this in an Array?” Once you put an associated type on a protocol in Swift today, it’s no longer a “thing.” It’s only a constraint that can be used for extensions and generic functions. It can’t put put in a variable, or be passed to a function, or in any other way be treated as a value.</p>

<p>Yes, someday <a href="https://robnapier.net/existential-spelling">generalized existentials</a> will improve this in some cases. But before you pine for those days, or reach for a <a href="https://robnapier.net/erasure">type-eraser</a>, it’s time to think harder about the protocol.</p>

<h2 id="whats-the-next-line-of-code">What’s the next line of code?</h2>

<p>I want to roll back to the Identifier protocol and ask that question, “would I ever want to put an Identifier in an Array?” I’ve used this protocol in production projects for a long time now, and the answer so far has been no. It just hasn’t come up. As I wrote this article, I tried to invent use cases that needed an Array of Identifiers, and each time the example kind of fell apart. I was always forcing it. But it’s worth walking through the thought process anyway.</p>

<p>If I try to create an Array of Identifiers today, it spits out that infamous error:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">ids</span><span class="p">:</span> <span class="p">[</span><span class="kt">Identifier</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="kt">User</span><span class="o">.</span><span class="kt">ID</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="kt">Document</span><span class="o">.</span><span class="kt">ID</span><span class="p">(</span><span class="s">"password"</span><span class="p">)]</span>
<span class="c1">// Protocol 'Identifier' can only be used as a generic constraint because it has Self or associated type requirements</span>
</code></pre></div></div>

<p>And this it the point where you cry out “generalized existential!” But that wouldn’t actually change anything. Let’s just imagine that we have a generalized existential or I’ve written an AnyIdentifier type-eraser. Eventually I’m going to wind up with some loop over <code class="language-plaintext highlighter-rouge">ids</code>:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="n">id</span> <span class="k">in</span> <span class="n">ids</span> <span class="p">{</span>
    <span class="c1">// ??? the only property is .value, which is an unknown type ???</span>
<span class="p">}</span>
</code></pre></div></div>

<p>I call this the “what now?” problem. The only thing I can do with <code class="language-plaintext highlighter-rouge">id</code> is get its value, because that’s the only thing in the protocol. But each ID can have a different value type. So what can I do with it? Even with the fabled generalized existential, the type of <code class="language-plaintext highlighter-rouge">.value</code> would have to be Any. What else could it be? I can’t call <code class="language-plaintext highlighter-rouge">fetch</code> with that. I don’t even know the Model type.</p>

<p><span class="pullquote-right" data-pullquote="If a type is solving your problems, it&#8217;s not wrong.">
“I don’t even know the Model type.” As I said, I’ve used this protocol in several projects and I’ve never needed a list of Identifiers, but as soon as I started writing this article, I realized how weird it is that an Identifier doesn’t know what type it identifies. Originally I was going to just rewrite this article to ignore it, but these kinds of…mistakes?…are important to explore. I hesitate to call it a mistake, because it’s never mattered in any shipping software I’ve worked on. If a type is solving your problems, it’s not wrong. But maybe it could be better.
</span></p>

<h2 id="when-you-think-about-it-everythings-a-function">When you think about it, everything’s a function.</h2>

<p>Before I make it better, I want to show how to solve a “what now?” problem <em>without</em> changing Identifier. I know that sounds a little strange, but sometimes you inherit types that you can’t easily change, and it’s good to have lots of tools in your belt that don’t require rewriting half your project every time something is less than ideal. So let me walk through an example where you think you want to use an Array of Identifiers, but don’t.</p>

<p>Let’s say that once an hour I want to refresh all the model objects by re-fetching them. So I build a list of Identifiers to refresh, and get the “can only be used as a generic constraint” error, and now have to decide what to do. The answer is to look again at what I really want. I don’t want a list of <em>Identifiers</em>. I want a list of <em>refresh requests</em>. A refresh request is a future action, and a future action is closure. I typically like to wrap that closure into a type. Maybe something specialized to this problem like:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">RefreshRequest</span> <span class="p">{</span>
    <span class="c1">// The delayed action to perform.</span>
    <span class="k">let</span> <span class="nv">perform</span><span class="p">:</span> <span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Void</span>

    <span class="kd">init</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">:</span> <span class="kt">Fetchable</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="kt">Model</span><span class="o">.</span><span class="kt">ID</span><span class="p">,</span>
                           <span class="n">with</span> <span class="nv">client</span><span class="p">:</span> <span class="kt">APIClient</span> <span class="o">=</span> <span class="kt">APIClient</span><span class="o">.</span><span class="n">shared</span><span class="p">,</span>
                           <span class="nv">updateHandler</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Model</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">,</span>    <span class="c1">// On success</span>
                           <span class="nv">errorHandler</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Model</span><span class="o">.</span><span class="kt">ID</span><span class="p">,</span> <span class="kt">Error</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span> <span class="o">=</span> <span class="n">logError</span><span class="p">)</span> <span class="c1">// On failure, with a default</span>
    <span class="p">{</span>
        <span class="c1">// Smash together updateHandler and errorHandler into a single () -&gt; Void.</span>
        <span class="n">perform</span> <span class="o">=</span> <span class="p">{</span>
            <span class="n">client</span><span class="o">.</span><span class="nf">fetch</span><span class="p">(</span><span class="kt">Model</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">id</span><span class="p">:</span> <span class="n">id</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">switch</span> <span class="nv">$0</span> <span class="p">{</span>
                <span class="k">case</span> <span class="o">.</span><span class="nf">success</span><span class="p">(</span><span class="k">let</span> <span class="nv">model</span><span class="p">):</span> <span class="nf">updateHandler</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>
                <span class="k">case</span> <span class="o">.</span><span class="nf">failure</span><span class="p">(</span><span class="k">let</span> <span class="nv">error</span><span class="p">):</span> <span class="nf">errorHandler</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="n">error</span><span class="p">)</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// Just a helper so errorHandler can have a default value</span>
    <span class="kd">static</span> <span class="kd">func</span> <span class="n">logError</span><span class="o">&lt;</span><span class="kt">ID</span><span class="p">:</span> <span class="kt">Identifier</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="kt">ID</span><span class="p">,</span> <span class="nv">error</span><span class="p">:</span> <span class="kt">Error</span><span class="p">)</span> <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"Failure fetching </span><span class="se">\(</span><span class="n">id</span><span class="se">)</span><span class="s">: </span><span class="se">\(</span><span class="n">error</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">let</span> <span class="nv">requests</span> <span class="o">=</span> <span class="p">[</span>
    <span class="kt">RefreshRequest</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="n">userID</span><span class="p">,</span> <span class="nv">updateHandler</span><span class="p">:</span> <span class="p">{</span> <span class="n">users</span><span class="p">[</span><span class="nv">$0</span><span class="o">.</span><span class="n">id</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$0</span> <span class="p">}),</span>
    <span class="kt">RefreshRequest</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="n">documentID</span><span class="p">,</span> <span class="nv">updateHandler</span><span class="p">:</span> <span class="p">{</span> <span class="n">documents</span><span class="p">[</span><span class="nv">$0</span><span class="o">.</span><span class="n">id</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$0</span> <span class="p">}),</span>
<span class="p">]</span>
</code></pre></div></div>

<p><span class="pullquote-right" data-pullquote="You don&#8217;t need to keep track of parameters (and their types) if all you need is the function itself.">
The point of all of this isn’t this specific data structure. It’s that <code class="language-plaintext highlighter-rouge">() -&gt; Void</code> is an incredibly powerful and flexible type, and you can construct it from all kinds of other functions. It’s another case of “common currency.” If you want a delayed action, that’s just a function. A lot of complicated generic code comes from trying to keep track of all the parameters to a generic function you intend to call later. You don’t need to keep track of parameters (and their types) if all you need is the function itself. This is the heart of <em>type-erasure</em> rather than focusing on <em>type-erasers</em>. It’s hiding types I don’t care about any more, like Model. Note in this example how two generic closures that rely on Model (<code class="language-plaintext highlighter-rouge">updateHandler</code> and <code class="language-plaintext highlighter-rouge">errorHandler</code>) are combined into a single <code class="language-plaintext highlighter-rouge">() -&gt; Void</code>, non-generic closure that relies on nothing. This is very common technique, and it’ll come up again in this series.
</span></p>

<p>There are more improvements I could make here. The basic closure <code class="language-plaintext highlighter-rouge">{ someModel[$0.id] = $0 }</code> is going to be duplicated a lot and I could fix that. But I’m going to leave it for now and focus on a better identifier.</p>

<h2 id="a-real-identifier">A Real Identifier</h2>

<p>What I really want is the model type to know its ID type, and the ID type to know its model type. If you remember the <code class="language-plaintext highlighter-rouge">APIClient.fetch</code> method, it takes both a type and an identifier:</p>

<pre>
func fetch&lt;Model: Fetchable&gt;(_ model: <span class="chl">Model.Type</span>, id: <span class="chl">Model.ID</span>,
                             completion: @escaping (Result&lt;Model, Error&gt;) -&gt; Void)
</pre>

<p>This creates awkward repetition in the API:</p>

<pre>
client.fetch(<span class="chl">User</span>.self, id: <span class="chl">User</span>.ID(1), completion: { print($0)} )
</pre>

<p>I could add an extra “Model” associated type to the Identifier protocol, but it gets a bit messy. Some of it is just Swift syntax (<code class="language-plaintext highlighter-rouge">where</code> clauses and the like), but it really comes down to Identifier not being a very good protocol. Look at the implementations:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">User</span><span class="o">.</span><span class="kt">ID</span><span class="p">:</span> <span class="kt">Identifier</span> <span class="p">{</span> <span class="k">let</span> <span class="nv">value</span><span class="p">:</span> <span class="kt">Int</span> <span class="p">}</span>
<span class="kd">struct</span> <span class="kt">Document</span><span class="o">.</span><span class="kt">ID</span><span class="p">:</span> <span class="kt">Identifier</span> <span class="p">{</span> <span class="k">let</span> <span class="nv">value</span><span class="p">:</span> <span class="kt">String</span> <span class="p">}</span>
</code></pre></div></div>

<p><span class="pullquote-right" data-pullquote="If every instance of a protocol conforms in exactly the same way, it should probably be a generic struct.">
If you think about any other implementations, they’re going to be almost identical: a struct with a single property called <code class="language-plaintext highlighter-rouge">value</code>. It’s hard to imagine any other way you’d want to implement this protocol. If every instance of a protocol conforms in exactly the same way, it should probably be a generic struct.
</span></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// An identifier (of some Value type) that applies to a specific Model type</span>
<span class="kd">struct</span> <span class="kt">Identifier</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">,</span> <span class="kt">Value</span><span class="o">&gt;</span> <span class="k">where</span> <span class="kt">Value</span><span class="p">:</span> <span class="kt">Codable</span> <span class="o">&amp;</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">value</span><span class="p">:</span> <span class="kt">Value</span>
    <span class="nf">init</span><span class="p">(</span><span class="n">_</span> <span class="nv">value</span><span class="p">:</span> <span class="kt">Value</span><span class="p">)</span> <span class="p">{</span> <span class="k">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span> <span class="p">}</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">Identifier</span><span class="p">:</span> <span class="kt">Codable</span><span class="p">,</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="nf">init</span><span class="p">(</span><span class="n">from</span> <span class="nv">decoder</span><span class="p">:</span> <span class="kt">Decoder</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="nf">init</span><span class="p">(</span><span class="k">try</span> <span class="n">decoder</span><span class="o">.</span><span class="nf">singleValueContainer</span><span class="p">()</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">Value</span><span class="o">.</span><span class="k">self</span><span class="p">))</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">encode</span><span class="p">(</span><span class="n">to</span> <span class="nv">encoder</span><span class="p">:</span> <span class="kt">Encoder</span><span class="p">)</span> <span class="k">throws</span> <span class="p">{</span>
        <span class="k">var</span> <span class="nv">container</span> <span class="o">=</span> <span class="n">encoder</span><span class="o">.</span><span class="nf">singleValueContainer</span><span class="p">()</span>
        <span class="k">try</span> <span class="n">container</span><span class="o">.</span><span class="nf">encode</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Identifier has two type parameters. The Model is the type this identifier applies to. The Value is the kind of identifier it requires (Int, UInt64, String, etc). The Model isn’t actually used anywhere, but it means that <code class="language-plaintext highlighter-rouge">Identifier&lt;User, Int&gt;</code> and <code class="language-plaintext highlighter-rouge">Identifier&lt;Document, Int&gt;</code> are completely different types and can’t be mixed up.</p>

<p>So User becomes:</p>

<pre>
struct User: Codable, Hashable {
    <span class="chl">let id: Identifier&lt;User, Int&gt;</span>
    let name: String
}
</pre>

<p>That’s ok, but it’d be nicer to typealias it so I can refer to User.ID as a type:</p>

<pre>
struct User: Codable, Hashable {
    <span class="chl">typealias ID = Identifier&lt;User, Int&gt;
    let id: ID</span>
    let name: String
}
</pre>

<p>And it can be even a little nicer if I extract a protocol, and apply it to Fetchable:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Something identified with an Identifier</span>
<span class="kd">protocol</span> <span class="kt">Identified</span><span class="p">:</span> <span class="kt">Codable</span> <span class="p">{</span>
    <span class="kd">associatedtype</span> <span class="kt">IDType</span><span class="p">:</span> <span class="kt">Codable</span> <span class="o">&amp;</span> <span class="kt">Hashable</span>
    <span class="kd">typealias</span> <span class="kt">ID</span> <span class="o">=</span> <span class="kt">Identifier</span><span class="o">&lt;</span><span class="k">Self</span><span class="p">,</span> <span class="kt">IDType</span><span class="o">&gt;</span>
    <span class="k">var</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">ID</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Something that can be fetched from the API by ID</span>
<span class="kd">protocol</span> <span class="kt">Fetchable</span><span class="p">:</span> <span class="kt">Identified</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">apiBase</span><span class="p">:</span> <span class="kt">String</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>  <span class="c1">// The part of the URL for this fetchable type</span>
<span class="p">}</span>

<span class="c1">// User model object</span>
<span class="kd">struct</span> <span class="kt">User</span><span class="p">:</span> <span class="kt">Identified</span> <span class="p">{</span>
    <span class="kd">typealias</span> <span class="kt">IDType</span> <span class="o">=</span> <span class="kt">Int</span>
    <span class="k">let</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">ID</span>
    <span class="k">let</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">User</span><span class="p">:</span> <span class="kt">Fetchable</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">apiBase</span><span class="p">:</span> <span class="kt">String</span> <span class="p">{</span> <span class="k">return</span> <span class="s">"user"</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And finally, <code class="language-plaintext highlighter-rouge">fetch</code> doesn’t need any type parameters. The only thing that could be fetched with a User.ID is a User:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="n">fetch</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">:</span> <span class="kt">Fetchable</span><span class="o">&gt;</span><span class="p">(</span><span class="n">_</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">Model</span><span class="o">.</span><span class="kt">ID</span><span class="p">,</span>
                             <span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span>

<span class="n">client</span><span class="o">.</span><span class="nf">fetch</span><span class="p">(</span><span class="kt">User</span><span class="o">.</span><span class="kt">ID</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nv">completion</span><span class="p">:</span> <span class="p">{</span> <span class="nf">print</span><span class="p">(</span><span class="nv">$0</span><span class="p">)}</span> <span class="p">)</span>
</code></pre></div></div>

<h2 id="trials-and-witnesses">Trials and Witnesses</h2>

<p>There are a lot of people who are a lot better than I am at this, and I’m sure they would have built this (or something better!) all at once on the first try. But I’m not bad at this stuff, and this is how it usually works for me. I want to stress that I’ve shipped the protocol version of Identifier successfully in several products, and have never run into a case where I actually wanted a more powerful Identifier that knew its Model. It’s just that by playing around (and thinking a lot about <a href="https://twitter.com/mbrandonw">Brandon Williams’</a> excellent <a href="https://www.youtube.com/watch?v=3BVkbWXcFS4">Protocol Witnesses</a> talk) I discovered another approach.</p>

<p>Of course I’ve never actually shipped this Identified protocol. Maybe I’m wrong. Maybe it has quirks when you try to use it in real code. Maybe it turns out to awkward or limited for some reason. I won’t know until I ship it in a production project.</p>

<p>I’ll now remind you that stdlib’s Collection protocol required <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0065-collections-move-indices.md">a pretty major overhaul</a> in Swift 3, and tweaks in <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0191-eliminate-indexdistance.md">Swift 4.1</a> and <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0232-remove-customization-points.md">Swift 5</a>. The stdlib team is <em>definitely</em> better at this than I am, and Collection is probably the most foundational and carefully considered protocol in Swift. And still, it’s hard to get it right on the first try. (For another major example, see the four iterations of <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md">Protocol-oriented integers</a>.)</p>

<p>Generic code is hard. There are trade-offs. Some things are hard because Swift is still evolving. And some things are hard because generic code is just hard. Build simply and concretely, and extract solutions as you discover problems. Don’t invent problems for yourself. “It isn’t generic enough” is not a problem. Make sure your generic code is solving a problem you really have, and put it off as long as you can get away with. You’ll probably have to redesign it anyway.</p>

<p>Next time I’ll move beyond fetching models. There are so many other things an API can do. What would that look like?</p>

<p><a href="https://robnapier.net/assets/protocols/StartWithAProtocol.zip">Swift Playground</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Protocols III: Existential Spelling]]></title>
    <link href="https://robnapier.net/existential-spelling"/>
    <updated>2019-05-12T00:00:00-04:00</updated>
    <id>https://robnapier.net/existential-spelling</id>
    <content type="html"><![CDATA[<p><em>This was supposed to be a quick sidebar, but it turned into a full-length article, so I’m calling it part 3. The original part 3, continuing the network stack, is mostly done, but I wanted to explain this weird word “existentials” first, and it turned out longer than I’d expected. Blame Joe Groff; he’s written too much interesting stuff lately and I want to talk about it.</em></p>

<p>If you’re interested in the future of generics in Swift, Joe Groff has a must-read post called <a href="https://forums.swift.org/t/improving-the-ui-of-generics/22814">Improving the UI of generics</a>. (You should also read the linked <a href="https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md">Generics Manifesto</a> for background.) In it, he touches on a common confusion in Swift. If you don’t understand what he’s talking about here, don’t worry. Explaining this paragraph is the point of this article.</p>

<blockquote>
  <p>We gave existential types an extremely lightweight spelling, just the bare protocol name, partially following the example of other languages like Java and C# where interfaces also serve as value-abstracted types, and partially out of a hope that they would “just work” the way people expect; if you want a type that can hold any type conforming to a protocol, just use the protocol as a type, and you don’t have to know what “existential” means or anything like that. In practice, for a number of reasons, this hasn’t worked out as smoothly as we had originally hoped. Although the syntax strongly suggests that the protocol as a constraint and the protocol as a type are one thing, in practice, they’re related but different things, and this manifests most confusingly in the “Protocol (the type) does not to conform to Protocol (the constraint)” error.
<!-- more --></p>
</blockquote>

<h2 id="spelling">Spelling?</h2>

<p>In programming languages, the “spelling” of something is the sequence of characters a programmer would type to represent a concept. This is often the most visible and argued-over part of a language. It’s also often a fairly shallow concern to the design, which is why it’s common to use intentionally bad “straw man” names to discuss a concept without getting bogged down in spelling. Consider the concept “true if <code class="language-plaintext highlighter-rouge">x</code>  or <code class="language-plaintext highlighter-rouge">y</code>, otherwise false.” Swift spells that  <code class="language-plaintext highlighter-rouge">x || y</code>. In <a href="https://en.wikipedia.org/wiki/Standard_ML">SML</a> the same concept is spelled <code class="language-plaintext highlighter-rouge">x orelse y</code>. But the spelling difference, the difference between the characters <code class="language-plaintext highlighter-rouge">||</code> and <code class="language-plaintext highlighter-rouge">orelse</code>, isn’t very important. It doesn’t tell you much about how the language works. A more interesting difference, at least to me, is that <code class="language-plaintext highlighter-rouge">||</code> is a <a href="https://github.com/apple/swift/blob/c2ecf6d9fb030e767f43bb85fc6ac862ec6fe493/stdlib/public/core/Bool.swift#L320-L323">stdlib function in Swift</a>, while <code class="language-plaintext highlighter-rouge">orelse</code> is hard-coded into the SML compiler, which would likely be true no matter how they were spelled.</p>

<p>In English, some spellings have multiple meanings. The same thing happens in programming languages, and it happened in the <a href="https://robnapier.net/a-mockery-of-protocols">last article</a>:</p>

<style>
    .chl { color: yellow; } /* code highlight */
</style>

<pre>
final class AddHeaders: <span class="chl">Transport</span>
{
    let base: <span class="chl">Transport</span>
    ...
}
</pre>

<p>The spelling “Transport” has two related, but distinct, meanings. The first refers to the <em>protocol</em> Transport. The second refers to the <em>existential of</em> Transport.</p>

<h2 id="existential">Existential?</h2>

<p>The “existential of a protocol” can mean several things, but here it refers to a compiler-generated box that holds a value that conforms to the protocol. To see why Swift needs this box, consider an Array of Transports:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// URLSession and TestTransport both conform to Transport</span>
<span class="k">var</span> <span class="nv">transports</span><span class="p">:</span> <span class="p">[</span><span class="kt">Transport</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="kt">URLSession</span><span class="o">.</span><span class="n">shared</span><span class="p">,</span> <span class="kt">TestTransport</span><span class="p">(</span><span class="o">...</span><span class="p">)]</span>
</code></pre></div></div>

<p>Swift would like to store Arrays contiguously in memory. So for an Array of Ints, the storage looks like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+---+---+---+
| 0 | 1 | 2 |
+---+---+---+
</code></pre></div></div>

<p>There are no pointers or indirection. The Ints are stored one after the other. To find the offset of index 2, you just have to multiply the size of an Int times two. That’s really fast and how you probably expect Arrays to work. Swift does the same thing for structs. It just lays them out field after field (there might be some padding, but that’s not important here).</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>struct S {
    let a: Int
    let b: Int
}

++--------+--------++--------+--------++--------+--------++
|| S[0].a | S[0].b || S[1].a | S[1].b || S[2].a | S[2].b ||
++--------+--------++--------+--------++--------+--------++
</code></pre></div></div>

<p>Again, to find the offset of <code class="language-plaintext highlighter-rouge">S[2]</code>, Swift just has to multiply two times the size of S (which is the same as two Ints). But what happens in a “protocol-typed” Array like <code class="language-plaintext highlighter-rouge">[Transport]</code>? Each element might be a different size. What can Swift do?</p>

<p>It makes a box that’s a fixed size (<a href="https://twitter.com/johannesweiss/status/1127858044640141312">currently five machine words, with three for storage</a>). If the type can fit in the box, then it’s stored in the box. If it can’t fit, then the compiler allocates some  space, copies the data there, and puts a pointer in the box. Reference types are already pointers, so it just puts the pointer in the box. In Swift, that box is called an <em>existential container</em>. The thing in the box is called a <em>witness</em>.</p>

<p><em>See <a href="https://developer.apple.com/videos/play/wwdc2016/416/">WWDC 2016: Understanding Swift Performance</a> for more on the implementation details.</em></p>

<h2 id="sure-but-existential">Sure, but “existential?”</h2>

<p><em>This section is a bit more technical; feel free to skip it if you like.</em></p>

<p>Why “existential?” Because the Transport protocol asserts that there <em>exists</em> some type that satisfies its requirements. By “some type,” I mean “in the universe of all possible types,” not “types that happen to be in your program.” That assertion may be wrong. It’s possible to define a protocol that nothing could ever conform to. For example:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Impossible</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="n">make</span><span class="o">&lt;</span><span class="kt">A</span><span class="o">&gt;</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">A</span> 
<span class="p">}</span>
</code></pre></div></div>

<p>(If you don’t believe me, spend some time trying to implement <code class="language-plaintext highlighter-rouge">make</code>. You need to return an instance of <em>whatever</em> the caller requests.)</p>

<p>An existential container is a placeholder box for some unknown type that satisfies the protocol. It’s possible there is no such type, or there may not be any such type in your program. Nothing can be done with it at runtime until a real, concrete value, a <em>witness</em>, is put in the box. The existence of a witness proves that such a type really does exist.</p>

<p>This implicit box isn’t the only example of an existential in Swift. The “Any” types like AnySequence, AnyHashable, and AnyKeyPath often get called “type-erasers” because they hide the concrete type, but they’re also explicit existentials. <a href="https://forums.swift.org/t/improving-the-ui-of-generics/22814#heading--clarifying-existentials">In future Swift,</a> we may spell implicit existentials as <code class="language-plaintext highlighter-rouge">any Transport</code> to parallel the explicit spelling.</p>

<p>While protocols create existential (“there exists”) types, generics create universal (“for all”) types. When you write <code class="language-plaintext highlighter-rouge">struct Array&lt;Element&gt; {...}</code>, that’s an assertion that “for all types (Element), there is another type (Array&lt;Element&gt;) with the following attributes….”</p>

<p>Existentials and universals are “duals,” which means that one can be transformed into the other without losing its structure. So AnySequence is a universal type (generic) that’s equivalent to an explicit existential of Sequence (protocol). That’s why when you run into problems with protocols, your solution may be to convert it into generic structs (or vice versa). They solve the same problems in different ways with different trade-offs.</p>

<h2 id="copy-values-or-code">Copy values or code?</h2>

<p>If you have a function with a parameter whose type is a protocol, that really means it requires an existential of that protocol.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Transport</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
<span class="kd">func</span> <span class="nf">transmit</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">,</span> <span class="n">over</span> <span class="nv">transport</span><span class="p">:</span> <span class="kt">Transport</span><span class="p">)</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
</code></pre></div></div>

<p>In order to call <code class="language-plaintext highlighter-rouge">transmit</code> with URLSession, Swift needs to copy the URLSession into an existential, and then pass that to <code class="language-plaintext highlighter-rouge">transmit</code>.</p>

<p>What if you used a generic function instead?</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="n">transmit</span><span class="o">&lt;</span><span class="kt">T</span><span class="p">:</span> <span class="kt">Transport</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="n">over</span> <span class="nv">transport</span><span class="p">:</span> <span class="kt">T</span><span class="p">)</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
</code></pre></div></div>

<p>This says that the caller gets to decide the type of T. If they pass URLSession, then the compiler creates an implicit overload:</p>

<pre>
func transmit(data: Data, over transport: <span class="chl">URLSession</span>) { ... }
</pre>

<p>If somewhere else in the code they pass TestTransport, then the compiler creates another overload:</p>

<pre>
func transmit(data: Data, over transport: <span class="chl">TestTransport</span>) { ... }
</pre>

<p>The entire <code class="language-plaintext highlighter-rouge">transmit</code> function is (in principle) copied, just as if you’d written an overload <code class="language-plaintext highlighter-rouge">transmit</code> for each type. This is an over-simplification, and the compiler may not actually make all the copies, or it may generate an existential version instead (or in addition). It depends on a lot of things, including the optimization flags. But when you call a generic function, you should think of it as creating a new version of the function written specifically for the type you called it with.<sup id="fnref:performance"><a href="#fn:performance" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<ul>
  <li>In an existential (protocol parameter) function, the parameters may need to be copied into an existential at <em>run-time</em>.</li>
  <li>In a generic function, duplicate copies of the code may be generated at <em>compile-time</em>.</li>
</ul>

<p>This run-time/compile-time distinction is a key difference between existentials and generics. Existentials are containers that are filled at run-time. Generics are compile-time functions for generating new code.</p>

<p>Existentials are used when you need to store heterogeneous values that are only known at run-time, for example in a heterogeneous collection.</p>

<p>Generics are used to apply algorithms to types that are known at compile-time. Protocols constrain what types can be used with those generics.</p>

<p>You don’t pass “a protocol value” to a function. You pass the existential of the protocol. Because Swift often converts concrete types into existentials for you, it’s easy to forget that they’re not the same thing. So when Swift doesn’t perform the conversion, it comes as a surprise, and we get the “can only be used as a generic constraint” (i.e. “as a protocol”) error.</p>

<h2 id="what-if-we-made-things-more-generallyumexistential">What if we made things more generally…um…existential?</h2>

<p>So couldn’t Swift just create an existential all the time, even for protocols with associated types (PATs)? Yes, but…it’s complicated. For the most common cases, yes, Swift could automatically create an <code class="language-plaintext highlighter-rouge">any Collection&lt;.Element == T&gt;</code><sup id="fnref:protocol-syntax"><a href="#fn:protocol-syntax" class="footnote" rel="footnote" role="doc-noteref">2</a></sup> implicit existential just like it currently has an <code class="language-plaintext highlighter-rouge">AnyCollection&lt;T&gt;</code> explicit existential. That idea is called <em>generalized existentials</em>, and I’m pretty certain Swift will add it eventually (maybe even soon). That’ll knock off several of protocols’ sharp edges for some of the most common cases.</p>

<p><span class="pullquote-right" data-pullquote="Many protocol problems I see in the wild are really just design problems that have little to do with missing Swift features.">
But it probably won’t solve as many problems as people expect. Many protocol problems I see in the wild are really just design problems that have little to do with missing Swift features. A generalized existential will get you past the compiler error, but in the process it may let you go much further down a wrong road.
</span></p>

<p>And there are many kinds of types that don’t lend themselves to automatically-generated existentials. The compiler can’t fulfill an <code class="language-plaintext highlighter-rouge">init</code> requirement or any <code class="language-plaintext highlighter-rouge">static</code> requirements on its own. It needs help from the programmer to determine what the default implementations are. It’s similar for protocols with a Self requirement. It may not always be possible to create a sensible default implementation. For protocols like Decodable that have no instance methods, an existential may not make sense at all.</p>

<h2 id="why-you-gotta-talk-about-math-so-much">Why you gotta talk about math so much?</h2>

<p>As Joe said, the hope was that existentials wouldn’t really matter. They’re created by the compiler, you can’t access them, and you can’t even refer to them directly in the language today. You’d think they’d be an implementation detail. But sometimes when you type the name of a protocol you mean the protocol and sometimes you mean the box, and sometimes that matters. We’d like to ignore reference counting, too, and mostly we can…except when we can’t.</p>

<p>The point of a protocol is algorithms. Protocols express what a type must be able to do in order to be used in certain ways. Ideally, protocols should have a very small number of requirements, and enable a large number of extensions and generic functions. A good protocol is short, but shows up in a lot of <code class="language-plaintext highlighter-rouge">where</code> clauses and extensions. They’re fundamentally about compile-time type concerns. “I want to apply this algorithm to many different concrete types.”</p>

<p>The point of an existential is heterogeneous collections, or “type-erasure” where you want to know less about the specific type and just use it according to an interface. They’re fundamentally about run-time values. “I want to assign values of many different concrete types to this variable.”</p>

<p>They’re not unrelated, but they’re not the same thing. When I say <a href="https://robnapier.net/nonconformist">“protocols do not (generally) conform to protocols,”</a> I <em>really</em> mean “existentials do not (generally) conform to protocols.” And when you see “can only be used as a generic constraint,” what the compiler is really telling you is that protocols with associated types (PATs) don’t have an existential.</p>

<h2 id="so-what-about-these-opaque-result-things">So what about these opaque result things?</h2>

<p>My hope is that after reading all this, you’ll feel more comfortable reading <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0244-opaque-result-types.md">SE-244</a>, which adds opaque return types in Swift 5.1. I don’t expect opaque return types to be an important feature for most developers. Please don’t assume you need to rewrite your code to use them. The problems they solve impact stdlib much more than day-to-day app development in my opinion. Looking over my code, I haven’t found a single place I want to use one.</p>

<p>The importance of SE-244 isn’t opaque return types. It’s that it lays the groundwork for the future of Swift generic code. If that interests you, then you definitely want to study it, and in particular get comfortable with <code class="language-plaintext highlighter-rouge">any P</code> (an existential) versus <code class="language-plaintext highlighter-rouge">some P</code> (an unknown but concrete type that conforms). Hopefully this article demystifies some of the terminology.</p>

<p>Next time, back to the networking stack and hopefully some more practical concerns.</p>

<hr />
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:performance">
      <p>All these “may” qualifiers are why you shouldn’t assume that protocols or generics are “better for performance” (for whatever meaning you’re attaching to “performance”). It depends on a lot of things. If your code is sensitive to the performance of generics or protocols, you need to profile it and look at what the compiler is actually generating. Do not take away from this discussion that “generics are faster” or “protocols create smaller binaries.” That might be true in certain cases, but it can also be the other way around. Write you code clearly and correctly, and say what you mean in types. The Swift compiler teams works very hard to make sure that kind of code will be performant. Don’t guess what the compiler will do. Test. <a href="#fnref:performance" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:protocol-syntax">
      <p>For an introduction to that proposed syntax, see the <a href="https://forums.swift.org/t/protocol-assoctype-t-shorthand-for-combined-protocol-and-associated-type-constraints-without-naming-the-constrained-type/21217">Protocol&lt;.AssocType == T&gt; shorthand</a> forum thread. <a href="#fnref:protocol-syntax" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Protocols II: A Mockery of Protocols]]></title>
    <link href="https://robnapier.net/a-mockery-of-protocols"/>
    <updated>2019-04-29T11:18:00-04:00</updated>
    <id>https://robnapier.net/a-mockery-of-protocols</id>
    <content type="html"><![CDATA[<p><a href="https://robnapier.net/start-with-a-protocol">In the last section</a>, I ended my little network stack at this point:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Something that can be fetched from the API</span>
<span class="kd">protocol</span> <span class="kt">Fetchable</span><span class="p">:</span> <span class="kt">Decodable</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">apiBase</span><span class="p">:</span> <span class="kt">String</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>  <span class="c1">// The part of the URL for this type</span>
<span class="p">}</span>

<span class="c1">// A client that fetches things from the API</span>
<span class="kd">final</span> <span class="kd">class</span> <span class="kt">APIClient</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">baseURL</span> <span class="o">=</span> <span class="kt">URL</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="s">"https://www.example.com"</span><span class="p">)</span><span class="o">!</span>
    <span class="k">let</span> <span class="nv">session</span><span class="p">:</span> <span class="kt">URLSession</span> <span class="o">=</span> <span class="kt">URLSession</span><span class="o">.</span><span class="n">shared</span>

    <span class="c1">// Fetch any Fetchable type given an ID, and return it asynchronously</span>
    <span class="kd">func</span> <span class="n">fetch</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">:</span> <span class="kt">Fetchable</span><span class="o">&gt;</span><span class="p">(</span><span class="n">_</span> <span class="nv">model</span><span class="p">:</span> <span class="kt">Model</span><span class="o">.</span><span class="k">Type</span><span class="p">,</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">Int</span><span class="p">,</span>
                                 <span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// Construct the URLRequest</span>
        <span class="k">let</span> <span class="nv">url</span> <span class="o">=</span> <span class="n">baseURL</span>
            <span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="kt">Model</span><span class="o">.</span><span class="n">apiBase</span><span class="p">)</span>
            <span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="s">"</span><span class="se">\(</span><span class="n">id</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
        <span class="k">let</span> <span class="nv">urlRequest</span> <span class="o">=</span> <span class="kt">URLRequest</span><span class="p">(</span><span class="nv">url</span><span class="p">:</span> <span class="n">url</span><span class="p">)</span>

        <span class="c1">// Send it to URLSession</span>
        <span class="k">let</span> <span class="nv">task</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="nf">dataTask</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">urlRequest</span><span class="p">)</span> <span class="p">{</span> <span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">error</span><span class="p">)</span> <span class="k">in</span>
            <span class="k">if</span> <span class="k">let</span> <span class="nv">error</span> <span class="o">=</span> <span class="n">error</span> <span class="p">{</span>
                <span class="nf">completion</span><span class="p">(</span><span class="o">.</span><span class="nf">failure</span><span class="p">(</span><span class="n">error</span><span class="p">))</span>
            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="n">data</span> <span class="p">{</span>
                <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="kt">Result</span> <span class="p">{</span> <span class="k">try</span> <span class="kt">JSONDecoder</span><span class="p">()</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">Model</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">from</span><span class="p">:</span> <span class="n">data</span><span class="p">)</span> <span class="p">}</span> 
                <span class="nf">completion</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="n">task</span><span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This can decode any Fetchable model from an API endpoint that has a URL something like <code class="language-plaintext highlighter-rouge">https://&lt;base&gt;/&lt;model&gt;/&lt;id&gt;</code>. That’s pretty good, but we can do a lot better. A natural first question is “how do I test it?” It relies explicitly on URLSession, which is very hard to test against. A natural approach would be to create a protocol to mock URLSession.</p>

<p>I hope by the time you’re done with this series, hearing “create a protocol to mock” makes you flinch just a little.
<!--more--></p>

<p><span class="pullquote-right" data-pullquote="If the only reason you can imagine using a protocol is for testing, then you&#8217;re not getting all you could out of it.">
The basic premise of a mock is to build a test object that mimics some other object you want to replace. That encourages you to design a protocol that very closely matches the existing interface, and then your “mock object” will also closely match that interface. This makes your “real” object, the protocol, and the mock evolve tightly in lockstep, and it cuts off opportunities for more powerful protocols that aren’t tied to one implementation. If the only reason you can imagine using a protocol is for testing, then you’re not getting all you could out of it. Protocols can be so much more.
</span></p>

<p>So my goal isn’t to “mock” URLSession, but to abstract the functionality I need. What I want is to map a URLRequest to Data, asynchronously:<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// A transport maps a URLRequest to Data, asynchronously</span>
<span class="kd">protocol</span> <span class="kt">Transport</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">send</span><span class="p">(</span><span class="nv">request</span><span class="p">:</span> <span class="kt">URLRequest</span><span class="p">,</span> <span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Data</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Notice that nothing about that says “HTTP server over the network.” Anything that can map a URLRequest to Data asynchronously is fine. It could be a database. It could be static unit test data. It could be flat files. It could be different routes depending on the scheme.</p>

<p>Now comes the power of retroactive modeling. I can extend URLSession to be a Transport:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">URLSession</span><span class="p">:</span> <span class="kt">Transport</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">send</span><span class="p">(</span><span class="nv">request</span><span class="p">:</span> <span class="kt">URLRequest</span><span class="p">,</span> <span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Data</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">let</span> <span class="nv">task</span> <span class="o">=</span> <span class="k">self</span><span class="o">.</span><span class="nf">dataTask</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">request</span><span class="p">)</span> <span class="p">{</span> <span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">error</span><span class="p">)</span> <span class="k">in</span>
            <span class="k">if</span> <span class="k">let</span> <span class="nv">error</span> <span class="o">=</span> <span class="n">error</span> <span class="p">{</span> <span class="nf">completion</span><span class="p">(</span><span class="o">.</span><span class="nf">failure</span><span class="p">(</span><span class="n">error</span><span class="p">))</span> <span class="p">}</span>
            <span class="k">else</span> <span class="k">if</span> <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="n">data</span> <span class="p">{</span> <span class="nf">completion</span><span class="p">(</span><span class="o">.</span><span class="nf">success</span><span class="p">(</span><span class="n">data</span><span class="p">))</span> <span class="p">}</span>
        <span class="p">}</span>
        <span class="n">task</span><span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And then anything that requires a Transport can use a URLSession directly. No need for wrappers or adapters. It just works, even though URLSession is a Foundation type and Apple doesn’t know anything about my Transport protocol. A few lines of code and it just works, without giving up any of the power of URLSession.</p>

<style>
    .chl { color: yellow; } /* code highlight */
</style>

<p>With that in place, <code class="language-plaintext highlighter-rouge">APIClient</code> can use Transport rather than URLSession.</p>

<pre>
final class APIClient {
    let baseURL = URL(string: &quot;https://www.example.com&quot;)!
    <span class="chl">let transport: Transport</span>   

    <span class="chl">init(transport: Transport = URLSession.shared) { self.transport = transport }</span>

    // Fetch any Fetchable type given an ID, and return it asynchronously
    func fetch&lt;Model: Fetchable&gt;(_ model: Model.Type, id: Int,
                                 completion: @escaping (Result&lt;Model, Error&gt;) -&gt; Void)
    {
        // Construct the URLRequest
        let url = baseURL
            .appendingPathComponent(Model.apiBase)
            .appendingPathComponent(&quot;\(id)&quot;)
        let urlRequest = URLRequest(url: url)

        // Send it to the transport
        <span class="chl">transport.send(request: urlRequest) { data in
            let result = Result { try JSONDecoder().decode(Model.self, from: data.get()) }
            completion(result)
        }</span>
    }
}
</pre>

<p>By using a default value in <code class="language-plaintext highlighter-rouge">init</code>, callers can still use the <code class="language-plaintext highlighter-rouge">APIClient()</code> syntax if they want the standard network transport.</p>

<p>Transport is a lot more powerful than just “a URLSession mock.” It’s a function that converts URLRequests into Data. That means it can be composed. I can build a Transport that wraps other Transports. For example, I can build a Transport that adds headers to every request.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Add headers to an existing transport</span>
<span class="kd">final</span> <span class="kd">class</span> <span class="kt">AddHeaders</span><span class="p">:</span> <span class="kt">Transport</span>
<span class="p">{</span>
    <span class="k">let</span> <span class="nv">base</span><span class="p">:</span> <span class="kt">Transport</span>
    <span class="k">var</span> <span class="nv">headers</span><span class="p">:</span> <span class="p">[</span><span class="kt">String</span><span class="p">:</span> <span class="kt">String</span><span class="p">]</span>

    <span class="nf">init</span><span class="p">(</span><span class="nv">base</span><span class="p">:</span> <span class="kt">Transport</span><span class="p">,</span> <span class="nv">headers</span><span class="p">:</span> <span class="p">[</span><span class="kt">String</span><span class="p">:</span> <span class="kt">String</span><span class="p">])</span> <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">base</span> <span class="o">=</span> <span class="n">base</span>
        <span class="k">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">send</span><span class="p">(</span><span class="nv">request</span><span class="p">:</span> <span class="kt">URLRequest</span><span class="p">,</span> <span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Data</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">var</span> <span class="nv">newRequest</span> <span class="o">=</span> <span class="n">request</span>
        <span class="k">for</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="k">in</span> <span class="n">headers</span> <span class="p">{</span> <span class="n">newRequest</span><span class="o">.</span><span class="nf">addValue</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nv">forHTTPHeaderField</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span> <span class="p">}</span>
        <span class="n">base</span><span class="o">.</span><span class="nf">send</span><span class="p">(</span><span class="nv">request</span><span class="p">:</span> <span class="n">newRequest</span><span class="p">,</span> <span class="nv">completion</span><span class="p">:</span> <span class="n">completion</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">let</span> <span class="nv">transport</span> <span class="o">=</span> <span class="kt">AddHeaders</span><span class="p">(</span><span class="nv">base</span><span class="p">:</span> <span class="kt">URLSession</span><span class="o">.</span><span class="n">shared</span><span class="p">,</span>
                           <span class="nv">headers</span><span class="p">:</span> <span class="p">[</span><span class="s">"Authorization"</span><span class="p">:</span> <span class="s">"..."</span><span class="p">])</span>
</code></pre></div></div>

<p>Now, rather than having every request deal with authorization, that can be centralized to a single Transport transparently. If the authorization token changes, then I can update a single object, and all future requests will get the right headers. But this is still unit testable (even the AddHeaders part). I can swap in whatever lower-level Transport I want.</p>

<p>This means I can extend existing systems in a really flexible way. I can add encryption or logging or caching or priority queues or automatic retries or whatever without intermingling that with the actual network layer. I can tunnel all the network traffic over a custom VPN protocol (I’ve done exactly that with a system like this), all without losing the ability to unit test. So yes, I get mocks, yes, I get unit testing, but I get so much more.</p>

<p>For completeness, here’s a “mock” Transport, but it’s probably the least interesting thing we can do with this protocol.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// A transport that returns static values for tests</span>
<span class="kd">enum</span> <span class="kt">TestTransportError</span><span class="p">:</span> <span class="kt">Swift</span><span class="o">.</span><span class="kt">Error</span> <span class="p">{</span> <span class="k">case</span> <span class="n">tooManyRequests</span> <span class="p">}</span>

<span class="kd">final</span> <span class="kd">class</span> <span class="kt">TestTransport</span><span class="p">:</span> <span class="kt">Transport</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">history</span><span class="p">:</span> <span class="p">[</span><span class="kt">URLRequest</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">var</span> <span class="nv">responseData</span><span class="p">:</span> <span class="p">[</span><span class="kt">Data</span><span class="p">]</span>

    <span class="nf">init</span><span class="p">(</span><span class="nv">responseData</span><span class="p">:</span> <span class="p">[</span><span class="kt">Data</span><span class="p">])</span> <span class="p">{</span> <span class="k">self</span><span class="o">.</span><span class="n">responseData</span> <span class="o">=</span> <span class="n">responseData</span> <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">send</span><span class="p">(</span><span class="nv">request</span><span class="p">:</span> <span class="kt">URLRequest</span><span class="p">,</span> <span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Data</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">history</span><span class="o">.</span><span class="nf">append</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
        <span class="k">if</span> <span class="o">!</span><span class="n">responseData</span><span class="o">.</span><span class="n">isEmpty</span> <span class="p">{</span>
            <span class="nf">completion</span><span class="p">(</span><span class="o">.</span><span class="nf">success</span><span class="p">(</span><span class="n">responseData</span><span class="o">.</span><span class="nf">removeFirst</span><span class="p">()))</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="nf">completion</span><span class="p">(</span><span class="o">.</span><span class="nf">failure</span><span class="p">(</span><span class="kt">TestTransportError</span><span class="o">.</span><span class="n">tooManyRequests</span><span class="p">))</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And I still haven’t used an associated type or a Self requirement. Transport doesn’t need any of that. It’s not even generic.</p>

<h2 id="common-currency">Common currency</h2>

<p>The split between a <code class="language-plaintext highlighter-rouge">APIClient.fetch</code>, which is generic, and <code class="language-plaintext highlighter-rouge">Transport.send</code>, which is not, is a common structure that I look for. <code class="language-plaintext highlighter-rouge">Transport.send</code> operates on a small set of concrete types: URLRequest in, Data out. When you’re working with a small set of concrete types, then composition is easy. Anything that can generate a URLRequest or can consume Data can participate. <code class="language-plaintext highlighter-rouge">APIClient.fetch</code> converts Data into any kind of generic Fetchable. When angle-brackets and associated types start creeping in, the code becomes more expressive, but harder to compose because you have to make sure all the types line up.</p>

<p>The power of the Internet is that it mostly operates on just one type: the packet. It doesn’t care what’s in the packet or what the packet “means.” It just moves packets from one place to another; packets in, packets out. And that’s why the Internet is so flexible, and the equipment that makes it work can be implemented by numerous vendors in wildly different ways, and they can all work together.</p>

<p>At each layer above the network layer, additional context and meaning is applied to the information. It’s interpreted as user information or commands to execute or video to display. That’s composition, gluing together independent layers, each with their own concerns. When designing protocols, I try to employ the same approach. Particularly at the lowest layers I look for common, concrete types to work with. URL and URLRequest. Data and Int. Simple functions like <code class="language-plaintext highlighter-rouge">() -&gt; Void</code>. As I move up the stack, then greater meaning is applied to the data in the form of model types and the like. That means it’s easy to write Transports and many different things can use Transports. And that’s the goal.</p>

<p>This network stack still is nowhere near as flexible and powerful as I want. But now it can fetch a wide variety of model types from a particular type of API in a very composable and testable way. That’s great progress. For some very simple APIs, it might even be done. There’s no need to make it more flexible for its own sake. But I think we’ll quickly find more features we need to add.</p>

<p>Next time, I’ll jump back up to the very top of the stack, to the models, and show where a PAT (protocol with associated type) can really shine.</p>

<p><a href="https://robnapier.net/assets/protocols/StartWithAProtocol.zip">Swift Playground</a></p>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>Throughout this series, whenever it’s unambiguous, I’ll refer to <code class="language-plaintext highlighter-rouge">Result&lt;Value, Error&gt;</code> as just “Value.” <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Protocols Sidebar I: Protocols Are Nonconformists]]></title>
    <link href="https://robnapier.net/nonconformist"/>
    <updated>2019-04-28T12:43:00-04:00</updated>
    <id>https://robnapier.net/nonconformist</id>
    <content type="html"><![CDATA[<p><a href="https://robnapier.net/start-with-a-protocol">Last time</a>, I mentioned something in passing:</p>

<blockquote>
  <p>I need a new protocol.</p>
</blockquote>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Fetchable</span><span class="p">:</span> <span class="kt">Decodable</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">apiBase</span><span class="p">:</span> <span class="kt">String</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<blockquote>
  <p>I need a protocol that requires that the type be Decodable, and also requires that it provide this extra string, <code class="language-plaintext highlighter-rouge">apiBase</code>.</p>
</blockquote>

<p>Read that again. It <em>requires</em> that the type be Decodable and also <em>requires</em> other things. I didn’t say that Fetchable <em>is</em> Decodable. It isn’t.
<!--more--></p>

<h2 id="protocols-do-not-conform">Protocols do not conform</h2>

<p>Protocols (with a few exceptions) do not conform to protocols, not even to themselves. A type that conforms to Fetchable, must also conform to Decodable, but Fetchable is not Decodable. Fetchable is not Fetchable. Decodable is not Decodable. Why do I keep repeating this. Because you will forget, and it will bite you. What would it mean if Decodable were Decodable?</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="n">decode</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">_</span> <span class="nv">type</span><span class="p">:</span> <span class="kt">T</span><span class="o">.</span><span class="k">Type</span><span class="p">,</span> <span class="n">from</span> <span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">T</span> <span class="k">where</span> <span class="kt">T</span> <span class="p">:</span> <span class="kt">Decodable</span>
</code></pre></div></div>

<p>Well, remember that JSONDecoder’s <code class="language-plaintext highlighter-rouge">decode</code> method requires a type that conforms to Decodable. If Decodable (or Fetchable) conformed to Decodable, I could write:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="k">try</span> <span class="kt">JSONDecoder</span><span class="p">()</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">Decodable</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">from</span><span class="p">:</span> <span class="n">data</span><span class="p">)</span>
</code></pre></div></div>

<p>And in fact, I see people try to write that all the time. But how could that possibly work? How can JSONDecoder know which of an unbounded number of possible types you want this JSON to be decoded into? Even if you did it, what could you possibly do with <code class="language-plaintext highlighter-rouge">result</code>? It’s only known method would be <code class="language-plaintext highlighter-rouge">init(from: Decoder)</code>. There are no instance methods on Decodable.</p>

<p>And so again: Protocols do not conform to protocols, not even to themselves.</p>

<h2 id="when-will-it-bite-me">When will it bite me?</h2>

<p>When I say this bites people all the time, here’s a common example: Say you have a protocol and an extension on Array:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">MyProtocol</span> <span class="p">{</span><span class="o">...</span><span class="p">}</span>

<span class="kd">extension</span> <span class="kt">Array</span> <span class="k">where</span> <span class="kt">Element</span><span class="p">:</span> <span class="kt">MyProtocol</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">doThing</span><span class="p">()</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And then you have some array of MyProtocol:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">things</span><span class="p">:</span> <span class="p">[</span><span class="kt">MyProtocol</span><span class="p">]</span> <span class="o">=</span> <span class="o">...</span>
</code></pre></div></div>

<p>You might imagine that you could call <code class="language-plaintext highlighter-rouge">things.doThing()</code>. After all, <code class="language-plaintext highlighter-rouge">doThing()</code> applies to any array of MyProtocol, and what’s more MyProtocol than MyProtocol? But that’s exactly what you can’t do. The syntax <code class="language-plaintext highlighter-rouge">where Element: MyProtocol</code> means “Element conforms to MyProtocol.” And as I’ve repeated many times now: MyProtocol does not conform to itself. In order to add an extension on <code class="language-plaintext highlighter-rouge">[MyProtocol]</code>, you would need to write an extension with <code class="language-plaintext highlighter-rouge">==</code> rather than <code class="language-plaintext highlighter-rouge">:</code>.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">Array</span> <span class="k">where</span> <span class="kt">Element</span> <span class="o">==</span> <span class="kt">MyProtocol</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">doThing</span><span class="p">()</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This says that Element <em>is exactly</em> MyProtocol. That doesn’t include types that conform to MyProtocol. It only applies exactly to <code class="language-plaintext highlighter-rouge">[MyProtocol]</code>.</p>

<h2 id="theres-always-usually-an-exception">There’s <strike>always</strike> usually an exception</h2>

<p>OK, what about the exceptions? There <em>are</em> a some protocols that do conform to themselves. <code class="language-plaintext highlighter-rouge">@objc</code> protocols do unless they have “static” requirements such as <code class="language-plaintext highlighter-rouge">init</code>, or static properties or methods. And in Swift 5, Error conforms to itself so that you can have “untyped error” Results like <code class="language-plaintext highlighter-rouge">Result&lt;T, Error&gt;</code>. If Error didn’t conform to itself, you’d have to use a concrete type for the error. But these are compiler-enforced special cases. You can’t make <em>your</em> protocol conform to itself.</p>

<h2 id="impossible-or-just-not-implemented">Impossible? Or just not implemented?</h2>

<p>But could they? Yes, some could in principle. The rule is pretty straightforward: if a protocol includes an <code class="language-plaintext highlighter-rouge">init</code> or <code class="language-plaintext highlighter-rouge">static</code> requirement, or includes a <code class="language-plaintext highlighter-rouge">Self</code> method parameter, then self-conformance is tricky. If there is no such requirement, then it it’s much more straightforward (basically the same as for <code class="language-plaintext highlighter-rouge">@objc</code>). There’s no deep reason that Encodable can’t be Encodable. The following could work, and I think would be both sensible and useful, it just doesn’t today:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">encodables</span><span class="p">:</span> <span class="p">[</span><span class="kt">Encodable</span><span class="p">]</span> <span class="o">=</span> <span class="o">...</span>
<span class="k">let</span> <span class="nv">json</span> <span class="o">=</span> <span class="k">try</span> <span class="kt">JSONEncoder</span><span class="p">()</span><span class="o">.</span><span class="nf">encode</span><span class="p">(</span><span class="n">encodables</span><span class="p">)</span>
</code></pre></div></div>

<p>Will this ever work? I don’t know. It’s been brought up a few times on <a href="https://forums.swift.org/t/will-existentials-ever-conform-to-their-protocols/4919">Swift Evolution</a>, and hasn’t been rejected outright. One concern is that adding an <code class="language-plaintext highlighter-rouge">init</code> requirement to an existing protocol could break existing usage (possibly in downstream code) in ways that might surprise developers. I haven’t found a clear statement, but it seems the team wants to make this work someday.</p>

<p>It’s even possible that “challenging” protocols could self-conform if there were default implementations. One could imagine a Swift where <code class="language-plaintext highlighter-rouge">Collection(1, 2, 3)</code> would return an Array in a Collection existential. (I’m not suggesting that would be a good idea; I really don’t know. It’s just that it’s the kind of thing one could imagine.)</p>

<p>In this series I’m generally going to talk about things I know from experience using today’s Swift or can predict about likely-near-term Swift (i.e. there’s an SE in the works). So any time I say something like “that won’t work,” I mean “without adding a significant feature to Swift that I don’t know is planned.” (Hopefully folks will continue to correct me if I’m misleading about how hard something would be.)</p>

<h2 id="i-of-course-mean-existentials">I of course mean “existentials”</h2>

<p>I want to talk about this more later, but when I say “a protocol doesn’t conform to itself,” it’s more accurate to say “the existential of a protocol doesn’t conform to that protocol.” But again, that’s for a later sidebar…. The thing to keep in mind is that these two things are different:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="n">f</span><span class="o">&lt;</span><span class="kt">T</span><span class="p">:</span> <span class="kt">P</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">t</span><span class="p">:</span> <span class="kt">T</span><span class="p">)</span>    <span class="c1">// This requires a concrete T that conforms to P</span>
<span class="kd">func</span> <span class="nf">f</span><span class="p">(</span><span class="nv">p</span><span class="p">:</span> <span class="kt">P</span><span class="p">)</span>          <span class="c1">// This requires a variable of type P (pedantically: "a P existential")</span>
</code></pre></div></div>

<p>So that’s just a quick side-bar. Next time, I’ll continue expanding the network stack.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Protocols I: "Start With a Protocol," He Said]]></title>
    <link href="https://robnapier.net/start-with-a-protocol"/>
    <updated>2019-04-22T00:00:00-04:00</updated>
    <id>https://robnapier.net/start-with-a-protocol</id>
    <content type="html"><![CDATA[<h2 id="in-the-beginning-crusty">In the beginning, Crusty</h2>

<p>In 2015, at WWDC, <a href="https://twitter.com/DaveAbrahams">Dave Abrahams</a> gave what I believe is still the greatest Swift talk ever given, and certainly the most influential. <a href="https://developer.apple.com/videos/play/wwdc2015/408/">”Protocol-Oriented Programming in Swift,”</a> or as it is more affectionately known, “The Crusty Talk.”</p>

<p>This is the talk that introduced the phrase “protocol oriented programming.” The first time I watched it, I took away just one key phrase:</p>

<blockquote>
  <p>Start with a protocol.</p>
</blockquote>

<p>And so, dutifully, I started with a protocol. I made a UserProtocol and a DocumentProtocol and a ShapeProtocol and on and on, and then started implementing all those protocols with generic subclasses and eventually I found myself in a corner.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Protocol 'P' can only be used as a generic constraint because it has Self or associated type requirements
</code></pre></div></div>

<p>And then I started throwing things.
<!--more--></p>

<p>For a couple of years, I was rather annoyed at the phrase “protocol-oriented programming.” If by “protocol” you just mean “interface,” then Go is much more “protocol oriented” than Swift. But the more I’ve wrestled with this new paradigm, the more I realized that protocols are more than just interfaces, and POP isn’t deeply about the protocols anyway. It’s about the extensions. But “extension-oriented programming” would be an even worse name. And more than extensions, it’s really, deeply, about generic algorithms. And “algorithm-oriented programming,” well, aren’t we all?</p>

<p>Naming a paradigm is always fraught with trouble. Most modern “object-oriented” languages aren’t object-oriented at all. They’re class-oriented (vs Smalltalk and JavaScript). And most “functional programming” languages are mostly value-oriented (vs FP and point-free). But the point of the names is shorthand for concepts bigger than a word, so let’s not get too caught up on the “protocol” in protocol-oriented programming. The Holy Roman Empire was in no way holy, nor Roman, nor an empire. Discuss.</p>

<h2 id="beware-quotes-traveling-sans-context">Beware quotes traveling sans context</h2>

<p>The famous “start with a protocol” quote is actually the end of a longer paragraph:</p>

<blockquote>
  <p>For example, if you want to write a generalized sort or binary search…Don’t start with a class. Start with a protocol.</p>
</blockquote>

<p>Or as Dave <a href="https://twitter.com/cocoaphony/status/1104114233288151043">clarified on Twitter</a>:</p>

<blockquote>
  <p>Use value types, then if you need polymorphism, make them conform to protocols.  Avoid classes.</p>
</blockquote>

<p><em>If</em> you’re reaching for class inheritance, try a protocol and value type instead. That’s very different from “start with a protocol for every problem.” <a href="https://twitter.com/AirspeedSwift">Ben Cohen</a> covered this in much more detail in the WWDC 2018 talk <a href="https://developer.apple.com/videos/play/wwdc2018/406/">Swift Generics (Expanded)</a>.</p>

<blockquote>
  <p>So notice that we considered a varied number of concrete types first. And now, we’re thinking about a kind of protocol that could join them all together. And, it’s important to think of things as this way around. To start with some concrete types, and then try and unify them with a protocol.</p>
</blockquote>

<p><span class="pullquote-right" data-pullquote="Write concrete code first. Then work out the generics.">
If you take away just one thing from this series, I want it to be this: <em>Write concrete code first. Then work out the generics.</em> Start with concrete types and clear use cases, and find the places that duplication happens. Then find abstractions. The power of protocol-oriented programming is that you don’t have to decide when you create a type exactly how it will be used. When you use class inheritance, you have to design your class hierarchy very early. But with protocols, you can wait until later.
</span></p>

<p>When I most get into trouble with protocols is when I try to write code “as generically as possible.” That doesn’t really mean anything. Abstractions are choices, and when you make a choice to be flexible in one direction, you generally make it harder to be flexible in other directions. Without some clear use cases, you don’t know what abstractions make sense.</p>

<p>So today, I want to come to protocol-oriented programming fresh, with a focus on very every-day problems we face when developing iOS apps in Swift.</p>

<h2 id="setting-the-stage">Setting the stage</h2>

<p>Over the next several articles I’ll be developing a very common system, a general-purpose networking stack that can fetch data asynchronously and decode arbitrary types. You may have built a system like this yourself in Swift. You may have used a framework that does it. The point of this exercise isn’t really the end result (though I think it’s quite useful code), but the process. What questions should you ask, and when, and how do you know what good answers look like? And most importantly, how does this “protocol-oriented” thing guide us? How is it different than other approaches?</p>

<p>I expect that you’re somewhat familiar with Swift, and particularly that you understand the syntax of generic functions and types, and have at least seen an <code class="language-plaintext highlighter-rouge">associatedtype</code> before. If you’re just getting started in Swift, maybe bookmark this series for later.</p>

<p>So to get started, I want to show a common starting point that never goes well for me. I’ve made this mistake many times, and I always find myself in a corner eventually. I see a lot of other people make this mistake, too.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// A network Request knows the URLRequest to fetch some data, and then can parse it.</span>
<span class="c1">// This will not go well.</span>
<span class="kd">protocol</span> <span class="kt">Request</span> <span class="p">{</span>
    <span class="kd">associatedtype</span> <span class="kt">Response</span>
    <span class="kd">func</span> <span class="nf">parse</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">Data</span><span class="p">)</span> <span class="k">throws</span> <span class="o">-&gt;</span> <span class="kt">Response</span>
    <span class="k">var</span> <span class="nv">urlRequest</span><span class="p">:</span> <span class="kt">URLRequest</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><span class="pullquote-right" data-pullquote="will I ever want to put this in an Array?">
How do I know this won’t go well? I’ll discuss it much more in depth later, but Request is a protocol with associated type (PAT). Any time you create a PAT, you should ask yourself “will I ever want to put this in an Array?” If the answer is yes, you don’t want a PAT. Requests are certainly something you’d want to put in an Array. Lists of pending requests, lists of requests that need to be retried, request priority queues. There are lots of reasons to put a Request in an Array.
</span></p>

<p>You might be tempted to look for a work-around, but don’t. Type-eraser? No. Generalized Existential?!?! …no… Even if you find some “work-around” to the problem at hand you’ll run into other walls very quickly (and I’ve seen that again and again). That “can only be used as a generic constraint” is telling you something important. This isn’t a problem with Swift. This just isn’t what PATs are for. There are other tools for this problem. In later articles I’ll explain why you don’t want these work-arounds, but the basic problem is starting with a protocol before we even know what algorithm we want to write.</p>

<p>So what does “know the algorithm” look like in practice?</p>

<h2 id="start-concrete">Start concrete</h2>

<p>A good way to find a generic algorithm is to start with several concrete algorithms, and then make a parameter out of what varies. In this case, I want to fetch several model types from an API and decode them. In order to start concretely, I’ll make some actual types.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">User</span><span class="p">:</span> <span class="kt">Codable</span><span class="p">,</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">Int</span>
    <span class="k">let</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">Document</span><span class="p">:</span> <span class="kt">Codable</span><span class="p">,</span> <span class="kt">Hashable</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">Int</span>
    <span class="k">let</span> <span class="nv">title</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This may not be our final implementations, but they’re good enough to get started. They’re pretty similar, but not identical, and that’s good for the first concrete types. I’ll want to push the envelope a bit more later, but this is good enough for now.</p>

<p>I also want a client to manage my connection to the server. I’m marking classes “final” to remind you that there’s no class inheritance here. I’m not suggesting you need to include “final” on all your class definitions. It’s not usually necessary. I’m making it a reference type because the client might eventually have some shared state. For example, if a login step were required, I’d want all references to the client to be logged in together.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// A client that fetches things from the API</span>
<span class="kd">final</span> <span class="kd">class</span> <span class="kt">APIClient</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">baseURL</span> <span class="o">=</span> <span class="kt">URL</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="s">"https://www.example.com"</span><span class="p">)</span><span class="o">!</span>
    <span class="k">let</span> <span class="nv">session</span> <span class="o">=</span> <span class="kt">URLSession</span><span class="o">.</span><span class="n">shared</span>

    <span class="c1">// ... methods to come ...</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And now I want the code to fetch and decode a User, as a method on APIClient.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">fetchUser</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="kt">Int</span><span class="p">,</span> <span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">User</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span>
<span class="p">{</span>
    <span class="c1">// Construct the URLRequest</span>
    <span class="k">let</span> <span class="nv">url</span> <span class="o">=</span> <span class="n">baseURL</span>
        <span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="s">"user"</span><span class="p">)</span>
        <span class="o">.</span><span class="nf">appendingPathComponent</span><span class="p">(</span><span class="s">"</span><span class="se">\(</span><span class="n">id</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
    <span class="k">let</span> <span class="nv">urlRequest</span> <span class="o">=</span> <span class="kt">URLRequest</span><span class="p">(</span><span class="nv">url</span><span class="p">:</span> <span class="n">url</span><span class="p">)</span>

    <span class="c1">// Send it to the URLSession</span>
    <span class="k">let</span> <span class="nv">task</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="nf">dataTask</span><span class="p">(</span><span class="nv">with</span><span class="p">:</span> <span class="n">urlRequest</span><span class="p">)</span> <span class="p">{</span> <span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">error</span><span class="p">)</span> <span class="k">in</span>
        <span class="k">if</span> <span class="k">let</span> <span class="nv">error</span> <span class="o">=</span> <span class="n">error</span> <span class="p">{</span> 
            <span class="nf">completion</span><span class="p">(</span><span class="o">.</span><span class="nf">failure</span><span class="p">(</span><span class="n">error</span><span class="p">))</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="k">let</span> <span class="nv">data</span> <span class="o">=</span> <span class="n">data</span> <span class="p">{</span>
            <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="kt">Result</span> <span class="p">{</span> <span class="k">try</span> <span class="kt">JSONDecoder</span><span class="p">()</span><span class="o">.</span><span class="nf">decode</span><span class="p">(</span><span class="kt">Model</span><span class="o">.</span><span class="k">self</span><span class="p">,</span> <span class="nv">from</span><span class="p">:</span> <span class="n">data</span><span class="p">)</span> <span class="p">}</span>
            <span class="nf">completion</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="n">task</span><span class="o">.</span><span class="nf">resume</span><span class="p">()</span>
<span class="p">}</span>
</code></pre></div></div>

<p>I’m sure many of you have written code kind of like this many times. Construct a URLRequest. Fetch it. Parse it. Pass it to the completion handler. Now, what does the code for <code class="language-plaintext highlighter-rouge">fetchDocument</code> look like?</p>

<style>
    .chl { color: yellow; } /* code highlight */
    .cer { color: red; } /* code error */
</style>

<pre>
func fetch<span class="chl">Document</span>(id: Int, completion: @escaping (Result&lt;<span class="chl">Document</span>, Error&gt;) -&gt; Void)
{
    // Construct the URLRequest
    let url = baseURL
        .appendingPathComponent(<span class="chl">"document"</span>)
        .appendingPathComponent("\(id)")
    let urlRequest = URLRequest(url: url)

    // Send it to the URLSession
    let task = session.dataTask(with: urlRequest) { (data, _, error) in
        if let error = error { 
            completion(.failure(error)) 
        } else if let data = data {
            let result = Result { try JSONDecoder().decode(<span class="chl">Document</span>.self, from: data) }
            completion(result)
        }
    }
    task.resume()
}
</pre>

<p>Unsurprisingly, <code class="language-plaintext highlighter-rouge">fetchDocument</code> is almost identical except for four changes: the function name, the type to pass to the closure, the URL path, and the type to decode. It’s so similar because I copied and pasted it. And when you find yourself copying and pasting, that’s where I know there’s probably some reusable code. So I extract that into a generic function:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="n">fetch</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">:</span> <span class="kt">Decodable</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">_</span><span class="p">:</span> <span class="kt">Model</span><span class="o">.</span><span class="k">Type</span><span class="p">,</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">Int</span><span class="p">,</span> 
                             <span class="nv">completion</span><span class="p">:</span> <span class="kd">@escaping</span> <span class="p">(</span><span class="kt">Result</span><span class="o">&lt;</span><span class="kt">Model</span><span class="p">,</span> <span class="kt">Error</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span>
<span class="p">{</span>
   <span class="o">...</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="where-should-type-parameters-go">Where should type parameters go?</h2>

<p>Before going on, it’s worth exploring the signature. Notice that I pass the type of Model as a parameter. It doesn’t even need a name, because the value won’t be used. It’s just there to nail down the type parameter in the function’s parameters rather than in completion handler’s parameters. I’m mostly doing this to show a technique, and because <code class="language-plaintext highlighter-rouge">fetch(2) { ... }</code> is a bit ambiguous to the reader (since all ID types are Int currently). Sometimes this makes sense, sometimes it doesn’t.</p>

<p>A good example where I think it makes a lot of sense is JSONDecoder’s <code class="language-plaintext highlighter-rouge">decode</code> method. It’s called this way:</p>

<pre>
let value = try JSONDecoder().decode(<span class="chl">Int.self</span>, from: data)
</pre>

<p>It could have been designed this way instead:</p>

<pre>
let value<span class="chl">: Int</span> = try JSONDecoder().decode(data)
</pre>

<p>It would have even been a little shorter that way. But it forces the caller to add a type annotation on the variable, which is a little ugly, and unusual in Swift. If the only place the type parameter shows up is in the return value, I usually recommend passing it as a parameter. But in any case, try writing some code with it, and focus on making things clear at the call-site. <sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<h2 id="making-fetch-generic">Making <code class="language-plaintext highlighter-rouge">fetch</code> generic</h2>

<p>Implementing <code class="language-plaintext highlighter-rouge">fetch</code> is pretty straightforward, except for one small <span class="cer">problem</span>:</p>

<pre>
func <span class="chl">fetch&lt;Model&gt;(_ model: Model.Type,</span> id: Int,
                  completion: @escaping (Result&lt;<span class="chl">Model</span>, Error&gt;) -&gt; Void)
    <span class="chl">where Model: Fetchable</span>
{
    // Construct the URLRequest
    let url =  baseURL
        .appendingPathComponent(<span class="cer">"??? user | document ???"</span>)
        .appendingPathComponent("\(id)")
    let urlRequest = URLRequest(url: url)

    // Send it to the URLSession
    let task = session.dataTask(with: urlRequest) { (data, _, error) in
        if let error = error { 
           completion(.failure(error)) 
        } else if let data = data {
            let result = Result { try JSONDecoder().decode(<span class="chl">Model</span>.self, from: data) }
            completion(result)
        }
    }
    task.resume()
}
</pre>

<p>There’s this string that’s either “user” or “document”. That’s something that this algorithm requires, but isn’t part of Decodable. So Decodable isn’t powerful enough to implement this. I need a new protocol.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Something that can be fetched from the API</span>
<span class="kd">protocol</span> <span class="kt">Fetchable</span><span class="p">:</span> <span class="kt">Decodable</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">apiBase</span><span class="p">:</span> <span class="kt">String</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>I need a protocol that requires that the type be Decodable, and also requires that it provide this extra string, <code class="language-plaintext highlighter-rouge">apiBase</code>. (See <a href="https://robnapier.net/nonconformist">Protocols are nonconformists</a> for more on the difference between “<em>requires</em> Decodable” and “<em>is</em> Decodable.”) With that, I can finish writing <code class="language-plaintext highlighter-rouge">fetch</code>:</p>

<pre>
// Fetch any Fetchable type given an ID, and return it asynchronously
func fetch&lt;Model&gt;(_ model: Model.Type, id: Int,
                  completion: @escaping (Result&lt;Model, Error&gt;) -&gt; Void)
    where Model: Fetchable
{
    let url = baseURL
        .appendingPathComponent(<span class="chl">Model.apiBase</span>)
        .appendingPathComponent("\(id)")
    let urlRequest = URLRequest(url: url)

    let task = session.dataTask(with: urlRequest) { (data, _, error) in
        if let error = error { completion(.failure(error)) }
        else if let data = data {
            let result = Result { try JSONDecoder().decode(Model.self, from: data) }
            completion(result)
        }
    }
    task.resume()
}
</pre>

<h2 id="retroactive-modeling">Retroactive modeling</h2>

<p>Now to use it, I need to make User and Document conform to Fetchable.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">User</span><span class="p">:</span> <span class="kt">Fetchable</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">apiBase</span><span class="p">:</span> <span class="kt">String</span> <span class="p">{</span> <span class="k">return</span> <span class="s">"user"</span> <span class="p">}</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">Document</span><span class="p">:</span> <span class="kt">Fetchable</span> <span class="p">{</span>
    <span class="kd">static</span> <span class="k">var</span> <span class="nv">apiBase</span><span class="p">:</span> <span class="kt">String</span> <span class="p">{</span> <span class="k">return</span> <span class="s">"document"</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>These tiny extensions represent one of the most powerful, and easiest to overlook, aspects of protocol-oriented programming: retroactive modeling. It is quite non-obvious that I can take a type like User that wasn’t designed to be Fetchable, and make it Fetchable in an extension. And that extension doesn’t even have to be in the same module. That’s not something you can typically do with class inheritance. You need to choose a superclass when you define a type.</p>

<p>I can take any type I want and conform it to my own protocols to use it in new and more powerful ways that the original type creator may never have thought of. There’s no need to tie User to this one use case and this one API. That’s why this protocol is called Fetchable rather than something like Model. It <em>isn’t</em> a “model.” It’s “something that can be fetched” and it only provides the methods and properties that allow that. I’m not suggesting that you should create a protocol for every use case, just the opposite. Really good protocols are usable by many algorithms. But you want most uses of the protocol to need most of the requirements. If the protocol is just a copy of the type’s entire API, it’s not doing its job. I’ll talk about that more in later articles.</p>

<h2 id="first-checkpoint">First checkpoint</h2>

<p>I know this has been basic so far. I know many of you “know all this.” This article is a warm-up, and the point of the exercise is not <em>what</em> was built, but <em>how</em> it was built. I started with simple, concrete code, and extracted first a generic function, and then a simple (no associated type) protocol. This is exactly the opposite of starting with a Request PAT and then trying to figure out the callers. This was just the first step. This system is nowhere near as flexible and powerful as it could be, but already it’s meeting the goal I set at the beginning: “fetch a several model types from an API and decode them.” Keep the current goal in mind and don’t let the protocols get out in front of you.</p>

<p>Next time, I’ll push this example further, and start seeing what protocol oriented programming can really accomplish. Eventually I’ll even need a PAT!</p>

<p><a href="https://robnapier.net/assets/protocols/StartWithAProtocol.zip">Swift Playground</a></p>

<p>(I don’t have comments on this site, but if you’re interested in any conversations about it, follow the thread on <a href="https://twitter.com/cocoaphony/status/1121549665789411333">Twitter</a>.)</p>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>A previous version of this post advocated for this approach much more strongly, but <a href="https://twitter.com/peres/status/1121824695211429888">some questions on Twitter</a> made me rethink this. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Conditional Breakpoint]]></title>
    <link href="https://robnapier.net/conditional-breakpoint"/>
    <updated>2017-04-23T11:59:20-04:00</updated>
    <id>https://robnapier.net/conditional-breakpoint</id>
    <content type="html"><![CDATA[<p><a href="https://twitter.com/jamesdempsey/status/855979622655291392">I’m now a Conditional Breakpoint.</a> It’s been a dream of mine for long time, and it finally happened at <a href="http://cocoaconf.com/chicago-2017/sessions/breakpoint-jam">CocoaConf Chicago</a>. There are folks who have played extensively with <a href="http://jamesdempsey.net/2013/03/02/introducing-the-breakpoint-jam-at-cocoaconf-chicago/">James Dempsey</a>, and those are the Breakpoints. If you’ve only played occasionally (even once), you’re a Conditional Breakpoint.
<!--more--></p>

<p>Originally, I wasn’t comfortable being a full “Conditional.” I’m not much of a guitarist. I can play along reasonably if there’s someone to cover my mistakes, and a group probably sounds slightly better with me than without. But listening to me play alone is an act of love and friendship, not something you’d do on purpose. So I kind of wanted to be called a “Provisional Breakpoint” instead. But that was wrong. Someone who’s played at a Breakpoint Jam is a Conditional Breakpoint. That’s what it means. If you’ve done it, you’ve earned it.</p>

<p>Everyone who played guitar that night was a Conditional, but <a href="https://twitter.com/designatednerd">Ellen Shapiro</a> was clearly our leader. She plays with an energy and style that I want to emulate. She’s much better than I am, but what I’ve played in years, she’s played in decades, so maybe that’s natural. <a href="https://robnapier.net/copying">Choosing the right people to copy is a worthwhile skill in itself.</a> There’s nothing wrong with being a beginner. There’s nothing wrong with learning and flailing and trying again. There’s nothing wrong with letting someone mentor you. And there are a lot of ways to mentor. You might not even know when you’re doing it.</p>

<p>When I first asked to play with the Breakpoints a few weeks ago, James said yes, and I immediately panicked a little on the inside, and I asked for the whole setlist so I could practice. And he said sure and sent them. But then he said, you know, it’s fine to just play some of the songs, or even drop out of parts if you’re not up for it. It’s better to have a few songs you’re good at than a bunch you stumble through. And I said yeah, yeah, yeah, I know that. I’m cool. And I did kind of know. But not really. I’d been planning to practice them all and just beat myself up a lot everywhere I stumbled. I needed someone who knows more than me to give me permission to be a beginner, but still let me play. Sometimes you’ll never know the impact of a small kindness.</p>

<p>After the show, <a href="https://twitter.com/ejknapp">Eric Knapp</a> asked me a very useful question. “So, that was your dream, and now you’ve done it. What’s your next dream?” It’s easy to lose your direction when you get to a destination. If you want to keep growing, your goals have to grow with you. My next goal is to be good enough that I can play alone and you’d rather stay than leave, even if you’re not my friend. It’s what I call “a mediocre guitarist.” Eric thought it was a good goal, but suggested a more concrete one: Play one song at an open mic night. And he passed on some wisdom he’d received and I needed. “Don’t wait until you’re ready. Go play before you’re ready. There are lessons you can only learn by doing.” Eric has forgotten more about playing than I know (and I don’t believe I’m exaggerating). It’s good advice.</p>

<p>I talk a bit about learning guitar and make a bit of noise about being a beginner. Some of that is because I love to tell stories, and I hope my stories can help other people. But of course saying “I’m a beginner” lowers expectations and overdone is a cheap way of getting praise. It’s a dangerous thing to make too big a deal about. For all my “I’m a beginner and I’m scared,” <a href="https://twitter.com/savinola">Laura Savino</a> has been playing guitar for less time than I have, and this <em>wasn’t</em> her first Breakpoint Jam. So sometimes the brave ones don’t make as much noise. You have to look or you’ll never notice.</p>

<p>I may just have been lucky so far, but I’ve found the guitar community to be incredibly welcoming. James isn’t alone in inviting beginners to play, but the Breakpoints has a special history of it. Except for Ellen, the rest of us (Laura, myself, and <a href="https://twitter.com/kognate">Josh Smith</a>) all made our first public performances at Breakpoint Jams. Creating that kind of opportunity is a gift and how you create and sustain a community. If we all “only hire the best,” where do you think the next generation will grow? Thankfully, James is willing to play with folks who are just trying their best. Are we as willing to develop software the same way?</p>

<p>There are senior developers and there are junior developers, and there are developers in between. Different people have different experience and skill. You might be a senior developer in one language or platform or style, and just learning another. But there’s no point talking about “real” developers. If you write software and it runs, you’re a real developer. That’s what it means. You develop software. If you’ve done it, you’ve earned it.</p>

<p>And if you develop software in Cocoa, then you really want to listen to <a href="https://itunes.apple.com/us/album/backtrace/id926558924">Backtrace</a>. Hope to see you at the <a href="http://jamesdempsey.net/splash/jdbp2017">next show</a> to benefit <a href="http://appcamp4girls.com">App Camp For Girls</a>!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Refactoring Slow and Steady]]></title>
    <link href="https://robnapier.net/refactoring"/>
    <updated>2017-02-13T12:21:55-05:00</updated>
    <id>https://robnapier.net/refactoring</id>
    <content type="html"><![CDATA[<p>I’ve been talking with folks on a Slack about refactoring today, and I thought I’d put some of my thoughts here. Maybe a little less polished than I’d like, but I wanted to get them out of my head and down on “paper.”</p>

<!--more-->

<p><em>The conversation started by referencing the classic Joel piece, <a href="https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/">Things You should Never Do, Part I</a>. Leading to my thoughts:</em></p>

<p>Just finished some major refactoring work, moving ObjC to Swift and completely redesigning its state machine. I absolutely stand behind the pieces I rewrote (which were a constant source of subtle race conditions and bugs, with every fix causing two new problems). I absolutely stand behind the pieces that I have delayed rewriting (which are a spaghetti mess, and incredibly difficult to safely modify, but after some minor tweaks are stable enough to leave alone).</p>

<p><span class="pullquote-right" data-pullquote="I’m a big fan of &#8220;radical refactoring.&#8221;">
I’m a big fan of “radical refactoring.” I’ve refactored several code bases until there was almost nothing left of the original code. But it was done steadily, only doing major rewrites to individual pieces after painstakingly detangling them from the rest of the code (usually over the course of several releases). And at the end, there was always some “ball of mud” part that was a bit crazy, but just worked and didn’t need to be touched that often, so we let it be.
</span></p>

<p>I’ve even refactored a C program into a Go program, by turning it into two independent processes that communicated over sockets, and moving bits from one side of the API to the other.</p>

<p>(So even “we need to switch languages/platforms entirely” doesn’t stop you from evolving towards a goal.)</p>

<p>But there’s an exception that Joel doesn’t mention (but I think Martin Fowler does): if you have incredibly <em>buggy</em> code, that is, if you <em>don’t</em> have working code, then that’s the time to consider a rewrite. Not ugly code. Not badly designed or horrible to work with code. But code that doesn’t actually work, and several attempts to make it work have failed. That’s when a rewrite (at least of those portions) is likely appropriate.</p>

<p><em>The discussion then turned to unit testing, and particluarly <a href="http://hamletdarcy.blogspot.com/2009/06/forgotten-refactorings.html">Forgotten Refactorings</a>.</em></p>

<p>Having had some very successful radical refactors on code without solid unit test coverage, I think it’s worth discussing how that can be done.</p>

<p><span class="pullquote-right" data-pullquote="redesigning for testablity will *itself* require massive refactoring without unit tests">
First, unit test coverage is absolutely the best first step. That said, sometimes it is impossible in any meaningful way. When all the most likely and common bugs in your system are race conditions and corner cases involving things outside the program (non-trivial networking, bluetooth, version-specific OS interactions, complex animations, etc), I’ve found unit tests rapidly become tests of mocks, and not tests of the system. We can debate whether or not it is possible or profitable to redesign your system so it is more testable. I’ll even concede that it is and leave arguments about TDD for another day (I’m actually a fan of TDD). But redesigning for testablity will <em>itself</em> require massive refactoring without unit tests (because you can’t unit test until you make it testable). Even if you have lots of tests, refactoring often means changing the tests dramatically (which means you’re not really testing the same thing). So at <em>some</em> point, you’re going to find yourself needing to refactor without perfect (or even barely sufficient) unit tests. How do you do it?
</span></p>

<p>Slow down.</p>

<p><span class="pullquote-right" data-pullquote="Slow. Down. Expect your refactor to take many releases.">
I cannot stress this enough. Slow. Down. Expect your refactor to take many releases. Do a small piece of refactoring, and run it through a full QA cycle (whatever that means for you) and ship it. Do it again and again. My “convert a C project to Go” project included a release where we just shipped the Go code alongside the C code, without even calling the Go code, just to prove it would install and not break anything. Then we built one, tiny, new feature in the Go code. It was so minor and impacted so few users, we were ready to declare it unsupported if it didn’t work. We’d been working on the Go code for almost two years before we cut over to it “for real” (and the vast majority of the code was still in C at that point). But at each step along the way, the system was better, and saner, and more reliable. And at each step along the way, it shipped, and got real field exercise. And we built a lot of tests for it, and we still found bugs that we were unable to build automated tests for. “Fails to determine domain on Mac previously joined to AD domain, but then removed, only on OS X prior to 10.8” or “SMB connection fails to Window 2000 server if username contains space” or “fails to determine correct IP address on Mac with case-sensitive file system if on Cisco VPN.” That kind of stuff.
</span></p>

<p>Second point that goes along with this is to keep your refactor steps contained. I’ve had so many experimental refactor branches that I threw away because they spiraled out of control and touched too many pieces of the system in non-trivial ways. Don’t be afraid to throw away several attempts at refactoring until you can get your change focused enough that the risk is contained. Sometimes that means creating “firebreaks,” an object that wraps the thing you’re refactoring and provides the old API for code you don’t want to touch yet. Creating a firebreak often starts as just a pass-through that does nothing but call methods on the original. Tedious, but often invaluable. They make it possible to move to your new API piece by piece rather than having to touch half the system in one go.</p>

<p>I strongly recommend keeping your commits very focused. “Rename FooAdapter to Foo” should be its own commit. Don’t mix it with changes to API. “Rename X to Y” commits are really easy to code review, even if they touch hundreds of files. But if you also changed logic in there, then it’s a monster. Similarly, anything that is an easy win with little risk (like naming things sanely, or moving some duplicated code into a function), do those first and get them into the main code base. That way, when you discover that your ambitious new design is out of control and have to start over, you don’t lose your easy wins.</p>

<p><span class="pullquote-right" data-pullquote="go slow and steady and keep shipping.">
Testing is great. Testing is critical. Testing is necessary. But unit testing is not sufficient. And when there are hundreds of test cases that need to be rewritten, they can be a <em>hindrance</em> to refactoring. The more important rule in my experience is go slow and steady and keep shipping.
</span></p>

<p>And yes. Write your unit tests. We’re professionals here.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Talking and Teaching]]></title>
    <link href="https://robnapier.net/talking"/>
    <updated>2016-11-29T10:35:09-05:00</updated>
    <id>https://robnapier.net/talking</id>
    <content type="html"><![CDATA[<p><a href="https://twitter.com/pepibumur">Pedro Piñera</a> makes some important points in his article <a href="http://ppinera.es/2016/11/16/in-a-world.html">In a world…</a>. There are a number of things in there, and you should go read it, but I want to focus on one part, which is the observation that the core “iOS speaker circle” is a fairly small group of people. Pedro notes:</p>

<blockquote>
  <p>There’s a huge difference when you compare a talk from someone that has been working a lot on the topic and from someone that studied the topic for giving a talk. Why do people do it then? Talks with a lot of value usually come from unknown people. From these people that from the anonymity worked on a topic and they achieved something that they were willing to share. … People don’t care about the company that person had worked for, or the newsletter that the person had written, but instead, what that person wants to share.</p>
</blockquote>

<p>While I agree with Pedro’s concern, I disagree that this is the proper ideal.</p>

<!--more-->

<p>I’ve learned more about programming from listening to <a href="https://twitter.com/dimsumthinking">Daniel Steinberg</a> talk about baking cookies than I have from a dozen talks from intelligent, highly experienced people who don’t have his skill for teaching. There are a number of speakers whose sessions I will attend no matter their topic because it’ll always be worth the time. I get inspired every time I listen to <a href="https://twitter.com/jaimeejaimee">Jaimee Newberry</a>, even though almost everything about her life and style is different than mine. If I watch <a href="https://twitter.com/chriseidhof">Chris Eidhof</a> live-code, I know I’m going to see some amazing idea that forces me to rethink something in my code.</p>

<p><span class="pullquote-right" data-pullquote="I absolutely care who&#8217;s giving the talk.">
I absolutely care who’s giving the talk. And if we’re going to ask people to spend hours or days of their time and hundreds or thousands of dollars to attend conferences, I think we owe the best we can offer.
</span></p>

<p>But while I disagree with some of Pedro’s analysis, he raises a very important point. A community with many teachers and broad sharing is better than one with few teachers and a hierarchical flow of knowledge. How do we improve?<sup id="fnref:marginalized"><a href="#fn:marginalized" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<p>We should recognize that there’s nothing wrong with having a core group of known, skilled speakers who draw a crowd. We should celebrate that. We should grow that group, and we should use them to make things even better.</p>

<p>At dotSwift, Daniel Steinberg reached out to all the speakers and offered assistance refining their talks. Conference organizers should encourage and facilitate that kind of mentorship, and use it to reduce the risks of inexperienced speakers. I hope conference organizers speak to each other and share names of promising speakers whom they didn’t have room for. CocoaHeads and other local groups should strive to video their local talks and <a href="http://cocoaheads.tv">make them available</a>. Conference organizers should use those to find and contact promising speakers outside the usual suspects. Local lightning talks have a very low barrier to entry and make an excellent way to get into speaking. Not everyone has a local group, but it’s a start.</p>

<p>For those without a local group to video them, I always recommend blogging. Learning to write well is a major part of learning to speak well, and the barrier to entry for blogs is lower. A blog doesn’t have to be constantly updated to be helpful. A single, well-written article can be a huge value. This is another important place for conference organizers to search for new speakers, and I think those who are already well known have a duty to amplify lesser-known blogs that are well written and insightful.</p>

<p>To those who want to speak, I’d like to offer a little advice. I’m not a top-tier speaker. I don’t get invited to many different conferences (thanks to <a href="http://cocoaconf.com">CocoaConf</a> for making room for me so often), and most of my CfP submissions are rejected, but I’ve spoken at 11 conferences over the last 4 years and some of my talks have been very well received, so take my advice for what it’s worth, remembering that it comes from someone with a lot of privilege. Not all of it applies easily to marginalized groups, but hopefully it can be of some help.</p>

<p>First, I want to quote Pedro again:</p>

<blockquote>
  <p>New announcements from Apple are the perfect source of topics for talks, grabbing it quickly is crucial: Protocol Oriented, Swift Open Source, Extension, Swift in the server… You can build your developer brand around the topic. After a few conferences talking about it, the community will tag you as the expert in the topic X. You might not have worked in a production environment with that new thing, you might not have faced the real use cases and issues, but documentation is perfect to prepare a talk based on it, isn’t it?</p>
</blockquote>

<p><span class="pullquote-right" data-pullquote="You don&#8217;t have to chase the &#8220;current cool thing.&#8221;">
Yes! I totally agree with most of this, except that this is <em>positive</em>. I take exception to a few points, though. First, “grabbing it quickly” is not crucial. Few people talk about Bluetooth or CoreMotion despite them being around for years. If those interest you, there’s plenty of room for new talks. (I sure would love some more on Bluetooth!) Would you be a better speaker if you shipped many production products with them? Of course. But you can still help a lot of people understand what’s possible by spending a few months going a little further than most and coming back and teaching. Don’t think you have to know everything before you’re allowed to say something! Just be honest and don’t pretend to know more than you do. There are many topics to explore. <a href="https://twitter.com/batalia">Natalia Berdys</a> gives a <a href="https://realm.io/news/tryswift-natalia-berdy-random-talk-consistent-world-noise-swift-gamekit-ios/">brilliant talk</a> on random number generation. You can’t get much more niche than that. You don’t have to chase the “current cool thing.”
</span></p>

<p>I don’t know how it is for most speakers, but for me, preparing a talk is very difficult. It took me nearly five months to develop my <a href="https://realm.io/news/tryswift-rob-napier-swift-legacy-functional-programming/">talk for try! Swift</a>. I completely rewrote it four times and practiced it for weeks. I think many speakers are much faster at this than I am, so it may not be so hard for you. But if you find it challenging and find yourself throwing away draft after draft because you can’t figure out what you’re trying to say, just know you’re not alone. If it matters to you, keep at it, and don’t be afraid to throw away a draft that isn’t working.<sup id="fnref:privilege"><a href="#fn:privilege" class="footnote" rel="footnote" role="doc-noteref">2</a></sup></p>

<p>If you want to give a talk, and think I can help you make it better, please reach out. I’ve critiqued talks before, and I’m happy to keep doing it. (I will start by asking you to evaluate the talk using <a href="http://www.slideshare.net/garrets/goethes-three-questions">Goethe’s Three Questions</a>. You have been warned.)</p>

<p>And if you read all this and say “hey, I don’t even <em>want</em> to give a talk,” that is absolutely fine. Most people don’t. As anyone who’s scheduled CocoaHeads talks before knows, public speaking isn’t for everyone and one reason there’s a small group who speaks so often is because they’re the ones willing to do it. It’s hard and it’s scary and it’s rewarding and it’s valuable. And sometimes it’s even fun. I hope we can include everyone who wants to be part of it. And I hope there’s always a venue for those who want to listen.</p>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:marginalized">
      <p>I’m only talking here about whether and how to broaden the number of unique speakers, because I believe this is Pedro’s point. I think there’s a different, very important discussion about diversity of background and drawing from marginalized groups. What I’m going to discuss can help, but that problem requires and deserves more targeted effort than I’m discussing here. <a href="#fnref:marginalized" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:privilege">
      <p>This advice assumes a lot of privilege. I know there are many people who don’t have the kind of time I do and don’t have the kind of family support I have. I don’t know the answer for that. If I didn’t have much of the privilege I have, I don’t know how I would speak at conferences. Take my advice for what it’s worth; it doesn’t apply to everyone. <a href="#fnref:privilege" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Copying]]></title>
    <link href="https://robnapier.net/copying"/>
    <updated>2016-09-03T13:56:14-04:00</updated>
    <id>https://robnapier.net/copying</id>
    <content type="html"><![CDATA[<p>I’m on my way back from <a href="http://tryswiftnyc.com">try! Swift</a>, which was fantastic. Of course it had those obvious things I’d hope for. Interesting talks, friendly people. Making new friends, and reuniting with old ones. But it also had some surprising delights and lessons.</p>

<p>I travel pretty well, but sometimes I make mistakes, and this was one of those times. The deodorant I thought I’d packed turned out to be body wash. Now there are a dozen reason that this shouldn’t really matter, and wouldn’t really matter given the A/C and the weather, etc., but I’m a product of my culture, and it was a bit stressful. I tried to find a drug store on the way to the conference, but I was afraid of being late and finally resigned myself to accepting things as they are and moving on.</p>

<p>And then, in the conference rest room, I discovered a small cache of toiletries under a try! Swift sign saying “if you need one, please take one.” I was dumbfounded. It was a very small kindness, but it mattered to me.
<!--more-->
I spoke to the conference organizer, <a href="https://twitter.com/NatashaTheRobot">Natasha</a>, to thank her. She immediately told me it wasn’t her idea, she’d just copied it from <a href="https://twitter.com/erikpub/">Erik Romijn</a>. I went to thank Erik, and he assured me it wasn’t his idea, he’d just copied it from Django conferences he’d been a part of. So I just wanted to say thanks to whomever came up with this very kind idea.</p>

<hr />

<p>To me, the best part of try! Swift was chatting with people during the breaks and in office hours. Hopefully the videos will be up soon, since I missed a few presentations due to conversations that ran long. So if you only “attend” by watching the videos online (like I did for the first one in Tokyo), you’ll unfortunately miss the best parts. I wish I could change that for you, but I can’t. I’m sorry.</p>

<p>One of the more interesting talks I had was about cut and pasting from Stack Overflow. This practice <a href="https://www.gitbook.com/book/tra38/essential-copying-and-pasting-from-stack-overflow/details">gets a lot of shaming</a>, and we were discussing that. I can’t promise that this conversation actually took the form of a Platonic dialog, but I can’t promise it didn’t, either. You’ll have to see me at a conference to find out.</p>

<p><strong>Anubis:</strong> I’ve only been programming for a little while. Swift is my first language, and I really don’t know anything yet. I find myself just searching Stack Overflow and cutting and pasting code. I know that’s a horrible way to program, but I don’t know what else to do. Before the Internet, I guess people had to figure it out themselves, but we’ve all gotten so lazy.</p>

<p><strong>Kakophonis:</strong> Most of my first years programming were just copying BASIC out of <a href="http://www.nibblemagazine.com/Nibble_Magazines.htm">Nibble magazine</a>.</p>

<p><strong>Anubis:</strong> You mean reading articles and implementing what they taught?</p>

<p><strong>Kakophonis:</strong> Oh, no. I mean typing hundreds and hundreds of lines of code for full programs that they included.</p>

<p><strong>Anubis:</strong> So you didn’t really learn much those first few years.</p>

<p><strong>Kakophonis:</strong> I learned a lot. I learned to use my tools. I learned to debug because I made a lot of typing mistakes. But most of all, I learned what good programs looked like. These were working programs written by good programmers. And I didn’t just read their code, I started changing it. Not a lot. I didn’t know a lot. But I learned to change the colors, or add a trivial feature, or just make random changes that made me happier with it.</p>

<p><strong>Anubis:</strong> When did you stop copying other people’s code and become a real programmer?</p>

<p><strong>Kakophonis:</strong> I copy code all the time.</p>

<p><strong>Anubis:</strong> As a short-cut, right? To make a deadline?</p>

<p><strong>Kakophonis:</strong> Not at all. I use others’ code whenever it’s beautiful and useful and they’ve shared it. But you’re right that I copy code a little differently than a beginner does.</p>

<p><strong>Anubis:</strong> How so?</p>

<p><span class="pullquote-right" data-pullquote="I usually retype the code by hand.">
<strong>Kakophonis:</strong> I rarely cut and paste. Maybe it’s a habit from my magazine days, but I usually retype the code by hand. Stack Overflow answers aren’t very long, and retyping gives me a chance to really think about what the code is doing. And then, if the code works and solves my problem, I usually restyle it to match my preferences and make it a little more my own. I almost always rename things. Sometimes I rewrite it from scratch. I make sure I know what each line does and why it’s there.
</span></p>

<p><strong>Anubis:</strong> Is that all?</p>

<p><strong>Kakophonis:</strong> If the code is more than a line or two, I generally add a comment crediting the source.</p>

<p><strong>Anubis:</strong> For politeness?</p>

<p><strong>Kakophonis:</strong> Yes, but more importantly, I want future maintainers, which is sometimes me, to know the context around the code, why it does things this way. That keeps them from creating regression bugs if they ever need to rewrite it further.</p>

<p><strong>Anubis:</strong> It sounds like you might learn more about programming from copying that way than from doing it yourself.</p>

<p><span class="pullquote-right" data-pullquote="A mark of a good programmer is the ability to distinguish what they should copy from what they shouldn&#8217;t.">
<strong>Kakophonis:</strong> Exactly. But copying only improves your code and your understanding if you choose the right things to copy. Many answers on Stack Overflow are incorrect, or they’re presented as magic incantations that may work, but are fragile. A mark of a good programmer is the ability to distinguish what they should copy from what they shouldn’t. Stack Overflow provides beginners some clues about quality, like votes and reputation and comments, but ultimately it’s experience that will help you recognize good code.
</span></p>

<p><strong>Anubis:</strong> So Stack Overflow doesn’t make us weak programmers?</p>

<p><strong>Kakophonis:</strong> It’s a tool. It is what you make of it. Programmers today have many more resources than they did before the Internet. It’s easy to think that the previous generations had it much harder. But computers and programs were also much, much simpler. No networking. No threading. Not even a GUI. I’m amazed that anyone is able to jump straight to building an iOS app with no programming experience. I had 25 years of experience before I encountered my first multi-threaded program. No, I don’t think beginning programmers today are weak.</p>

<hr />

<p>Sometimes life is not unlike programming. Who and what we choose to copy says a lot about us. Choosing to use someone’s idea is still a choice. Give credit to your inspirations, but don’t discount the wisdom in picking something beautiful to copy.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Inspiration]]></title>
    <link href="https://robnapier.net/inspiration"/>
    <updated>2016-08-26T15:46:27-04:00</updated>
    <id>https://robnapier.net/inspiration</id>
    <content type="html"><![CDATA[<p>As a speaker, writer, and member of our community, <a href="http://dimsumthinking.com">Daniel Steinberg</a> is my inspiration. That’s not a secret. If you and I have spent much time talking after a conference, I’ve probably mentioned it. It’s not the sort of thing you usually say to someone, and I don’t think I ever have, but I’ve learned a lot from his speaking style, and I constantly try to live up to his standard of kindness. I’m not by nature very kind, so if you see me behaving that way, I’m likely trying to do what I think Daniel might.</p>

<p>This isn’t to say we’re close. We see each other at conferences. We email and tweet. We’re members of a community. So of course I have some idealized picture of him in my mind, without all the this and that of a real person. Even so, he inspires me. When my wife, Janet, and I talk about what’s ahead for our future, we always talk about Daniel and his wife, Kim. I’ve seen them at conferences, traveling together, independent but a team, and I think, hey, we could pull that off when the kids go to school. And Janet and I talk about how to make that work. And we know we only have the shallowest understanding of their real lives, but they inspire us.</p>

<p>Kim died this week. I didn’t know her well. We’d met, and she was nice to me. She and Daniel always seemed so “together” even when they were apart most of the day. Hearing the news unmoored me and scared me and made me think about myself and my family and my plans. And then my heart broke for Daniel.</p>

<p>I’m not kind by nature. But I’m part of a community that is, and part of that is Daniel’s influence on us. <a href="https://twitter.com/designatednerd">Ellen Shapiro</a> has been kind and <a href="http://support.smiletrain.org/site/RedirectHandler?type=goto&amp;key=ios-for-kim">set up a fund</a> to let us support SmileTrain, where Daniel and his daughter Maggie have asked us to give in Kim’s name. I had never heard of SmileTrain, but it is so perfect. It is kind. And it is practical. It is literally the gift of a smile. It is Daniel and Kim.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[NSData, My Old Friend]]></title>
    <link href="https://robnapier.net/nsdata"/>
    <updated>2015-10-07T20:27:00-04:00</updated>
    <id>https://robnapier.net/nsdata</id>
    <content type="html"><![CDATA[<h2 id="or-how-i-learned-to-stop-worrying-and-love-foundation">Or… “How I learned to stop worrying, and love Foundation.”</h2>

<blockquote>
  <p>Forgive me, NSData. I was running around with that flashy [UInt8], acting like you didn’t have everything I need. I’ve learned my lesson.</p>

  <p>— Rob Napier (@cocoaphony) <a href="https://twitter.com/cocoaphony/status/648514927678910464">September 28, 2015</a></p>
</blockquote>

<p>I did a lot of writing and rewriting of the <a href="https://github.com/RNCryptor/RNCryptor/releases/tag/RNCryptor-4.0.0-beta.1">Swift version of RNCryptor</a>. I struggled especially with what type to use for data. I gravitated quickly to <code class="language-plaintext highlighter-rouge">[UInt8]</code> with all its apparent Swiftiness. But in the end, after many iterations, I refactored back to <code class="language-plaintext highlighter-rouge">NSData</code>, and I’m really glad I did.</p>

<p>This is the story of why.
<!-- MORE --></p>

<h3 id="in-fair-frameworks-where-we-lay-our-scene">In fair frameworks, where we lay our scene</h3>

<p>First, I want to be clear that I don’t think <code class="language-plaintext highlighter-rouge">[UInt8]</code> is bad. In some places it’s better than <code class="language-plaintext highlighter-rouge">NSData</code>, but there are tradeoffs, and ultimately I found the tradeoffs favored <code class="language-plaintext highlighter-rouge">NSData</code> today. Some of those will improve in Future Swift, and I suspect something more Swifty than <code class="language-plaintext highlighter-rouge">NSData</code> will be the way of the future. But today, in the kinds of projects I work on, there’s a lot going for <code class="language-plaintext highlighter-rouge">NSData</code>.</p>

<p>“In the kinds of projects I work on” is an important caveat. I mostly build things that are used by other developers; frameworks, engines, services, even just snippets of code. I don’t build a lot of full applications that an end user would see. And the systems I build typically have a very small API surface. They typically do just one thing, and they’re built to be easily clicked together with things that I didn’t write.</p>

<p>To achieve that, I try to make most of my code as self-contained as possible, with minimal dependencies. I try to make it easy to plug into whatever system you prefer. That usually means sticking as much as possible to the types provided by the system. Much as I love <a href="https://github.com/antitypical/Result"><code class="language-plaintext highlighter-rouge">Result</code></a>, none of my systems use it externally (and only a few use it internally). I try to avoid exposing my caller to any cleverness. If they’re familiar with the platform, I want them to find my API obvious, even boring. If they have a preferred error handling system, they probably have a way to convert <code class="language-plaintext highlighter-rouge">throws</code> to it, since that’s what Cocoa generates. So I use <code class="language-plaintext highlighter-rouge">throws</code>.</p>

<h3 id="the-elephant-in-the-room">The elephant in the room</h3>

<p>I see a lot of Swift devs behaving as though Cocoa has somehow disappeared. Cocoa has become the embarrassing uncle that no one wants to acknowledge, even though he’s sitting right there at Thanksgiving dinner passing you the potatoes. And this is crazy. First, Cocoa is a <em>great</em> framework, filled with all kinds of tools that we use every day, implemented well and refined for years. And second, Cocoa is a <em>required</em> framework, filled with tools that we <em>have</em> to use every day if we want to write apps.</p>

<p>Trying to cordon off Cocoa means constantly converting your types and patterns. That’s horrible for programs, and it’s very unswifty. Swift is all about integrating cleanly with Cocoa.</p>

<p>If you’re writing Cocoa apps you wind up with <code class="language-plaintext highlighter-rouge">NSData</code> all the time. You get it when you read or write files, when you download things from the network, when you create PNGs, when you serialize. You can’t escape <code class="language-plaintext highlighter-rouge">NSData</code>. Swift automatically bridges <code class="language-plaintext highlighter-rouge">NSString</code> and <code class="language-plaintext highlighter-rouge">String</code>, <code class="language-plaintext highlighter-rouge">NSArray</code> and <code class="language-plaintext highlighter-rouge">Array</code>, <code class="language-plaintext highlighter-rouge">NSError</code> and <code class="language-plaintext highlighter-rouge">ErrorType</code>. Some day I hope <a href="http://www.openradar.me/23010231"><code class="language-plaintext highlighter-rouge">NSData</code> gets a bridge</a>, but it doesn’t have one today. So the question is what to do in the meantime?</p>

<p>There are basically two options: build the bridge or use <code class="language-plaintext highlighter-rouge">NSData</code>. Building the bridge (without modifying stdlib) is tricky if you want to avoid copying. It’s not hard if you’re not worried about performance, but an <code class="language-plaintext highlighter-rouge">NSData</code> can easily be multiple megabytes and that’s both time and memory. Even temporary copies raise your high water mark, which hurts the whole system. Yes, I know all about premature optimization, but when you’re building frameworks you need to avoid patterns that are reasonably likely to cause performance problems. Even when you’re building just one app, there’s a difference between “build simply, then optimize” and “throw performance out the window until Apple rejects your app, then optimize.” If it were just one copy, and it made everything else really simple, that might be worth discussing. But making a copy every time you move from one part of the system to another is a problem.</p>

<p>With enough work you can solve this problem. It’s not tons of code, but it is a little bit tricky to be certain you’ve done it exactly right and won’t leak or crash (and much trickier to do from outside of stdlib). But is that work and complexity worth it? What problems were we really solving converting <code class="language-plaintext highlighter-rouge">NSData</code> to <code class="language-plaintext highlighter-rouge">[UInt8]</code>?</p>

<h3 id="the-magic-that-is-array">The magic that is <code class="language-plaintext highlighter-rouge">Array</code></h3>

<p>Even if you don’t care about <code class="language-plaintext highlighter-rouge">NSData</code> interop, using <code class="language-plaintext highlighter-rouge">[UInt8]</code> doesn’t give you a magical unicorn API. <code class="language-plaintext highlighter-rouge">Array</code> has all kinds of little sharp edges that surprise and confuse if you want to very careful of making copies.</p>

<p>Let’s start with a simple function using <code class="language-plaintext highlighter-rouge">NSData</code> and see what happens with <code class="language-plaintext highlighter-rouge">[UInt8]</code>. This function takes a <code class="language-plaintext highlighter-rouge">CCCryptorRef</code> and updates it with some data, writes the resulting encrypted data to a buffer and returns the buffer.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>func updateCryptor(cryptor: CCCryptorRef, data: NSData) -&gt; NSData {
    let outputLength = CCCryptorGetOutputLength(cryptor, data.length, false)
    let buffer = NSMutableData(length: outputLength)!
    var dataOutMoved: Int = 0

    let result = CCCryptorUpdate(cryptor,
        data.bytes, data.length,
        buffer.mutableBytes, buffer.length,
        &amp;dataOutMoved)
    guard result == 0 else { fatalError() }

    buffer.length = dataOutMoved
    return buffer
}
</code></pre></div></div>

<p>No problems there IMO. That’s a fine implementation. Easy to read and understand (if you understand <code class="language-plaintext highlighter-rouge">CCCryptorRef</code>). The <code class="language-plaintext highlighter-rouge">[UInt8]</code> implementation is about the same. I don’t think you could say one is really much cleaner than the other.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>func updateCryptor_(cryptor: CCCryptorRef, data: [UInt8]) -&gt; [UInt8] {
    let outputLength = CCCryptorGetOutputLength(cryptor, data.length, false)
    var buffer = [UInt8](count: outputLength, repeatedValue: 0)
    var dataOutMoved: Int = 0

    let result = CCCryptorUpdate(cryptor,
        data, data.count,
        &amp;buffer, buffer.count,
        &amp;dataOutMoved)
    guard result == 0 else { fatalError() }

    buffer[dataOutMoved..&lt;buffer.endIndex] = []
    return buffer
}
</code></pre></div></div>

<p>But is it correct? Can we be certain that <code class="language-plaintext highlighter-rouge">data</code> is contiguous memory and isn’t really an <code class="language-plaintext highlighter-rouge">NSArray&lt;NSNumber&gt;</code> under the covers? If it is an <code class="language-plaintext highlighter-rouge">NSArray</code>, will this work or will we get the wrong data? Should we use <code class="language-plaintext highlighter-rouge">.withUnsafePointer</code> here? I studied the docs, and talked to several devs (including Apple devs), and in the end am pretty sure that this will always work. But I’m only “pretty sure.” And that’s only because of kind people at Apple (especially @jckarter) taking time to walk through it with me. Not everyone has that.</p>

<p>This “but is it correct?” came up all over the place. Would this operation cause a copy? Exactly how long is an <code class="language-plaintext highlighter-rouge">UnsafeBufferPointer</code> valid? There’s a lot of bridging magic in <code class="language-plaintext highlighter-rouge">Array</code>, and it’s not always clear what is <em>promised</em>. Testing only gets you so far if the current implementation just happens to work. Sometimes behaviors change just by importing Foundation.</p>

<p>I thought I might avoid the Cocoa-bridging ambiguities of <code class="language-plaintext highlighter-rouge">Array</code> by using <code class="language-plaintext highlighter-rouge">ContiguousArray</code> instead. That way I could be very precise about my expectations. But it turns out that passing <code class="language-plaintext highlighter-rouge">ContiguousArray</code> to C behaves very differently than passing <code class="language-plaintext highlighter-rouge">Array</code>. <code class="language-plaintext highlighter-rouge">Array</code> gets turned into a pointer to the first element, but <code class="language-plaintext highlighter-rouge">ContiguousArray</code> gets turned into a pointer to the struct. So the <code class="language-plaintext highlighter-rouge">ContiguousArray</code> gets corrupted and you crash. <code class="language-plaintext highlighter-rouge">Array</code> is more magical than you think. Magic is wonderful until your program crashes and you don’t know why.</p>

<p>I struggled with copy-on-write behavior. How do I know if an array’s buffer is shared so that a copy will happen on mutation? Will this code allocate 10MB or 20MB?</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>func makeArray() -&gt; [UInt8] {
    return Array(count: 10_000_000, repeatedValue: 0)
}
var array = makeArray() + [1]
</code></pre></div></div>

<p>What tests would prove that? Is it promised or just the current implementation? Does optimization level matter? Is it the same if <code class="language-plaintext highlighter-rouge">makeArray()</code> is in another module than the caller? Would small changes in my code lead to dramatic and surprising performance changes in apps that use my framework? This was a common problem in Scala before the <code class="language-plaintext highlighter-rouge">@tailrec</code> annotation was added. Very small tweaks to a recursive function could cause your stack to explode because you quietly broke tail call optimization. All your unit tests still pass, but the program crashes.</p>

<p>In the end, I spent hours trying to be certain of the precise behaviors of <code class="language-plaintext highlighter-rouge">Array</code> bridging and copying. And all that to replace <code class="language-plaintext highlighter-rouge">NSData</code> code that is perfectly fine.</p>

<h3 id="slice-and-dice">Slice and dice</h3>

<p>When updating the cryptor, it is common that you’ll only want some of the data you were passed. You might want to slice off a header, or you might want to chunk the data up to reduce your encryption buffer size. In either case, you want to pass <code class="language-plaintext highlighter-rouge">updateCryptor()</code> a slice.</p>

<p>For an immutable <code class="language-plaintext highlighter-rouge">NSData</code> that’s easy. Call <code class="language-plaintext highlighter-rouge">.subdataWithRange()</code> and you get another <code class="language-plaintext highlighter-rouge">NSData</code> back with no copying.</p>

<p>But the <code class="language-plaintext highlighter-rouge">SubSequence</code> of <code class="language-plaintext highlighter-rouge">Array</code> is <code class="language-plaintext highlighter-rouge">ArraySlice</code>, and <code class="language-plaintext highlighter-rouge">updateCryptor()</code> doesn’t accept that. Of course you can copy your slice into a new <code class="language-plaintext highlighter-rouge">Array</code>, but unnecessary copying was what we wanted to avoid.</p>

<p>We could make all the functions take <code class="language-plaintext highlighter-rouge">ArraySlice</code> and overload all the functions with an <code class="language-plaintext highlighter-rouge">Array</code> interface that forwards to the <code class="language-plaintext highlighter-rouge">ArraySlice</code> interface. But it’s a lot of duplication.</p>

<p>So I decided to just convert everything to <code class="language-plaintext highlighter-rouge">UnsafeBufferPointer</code> and then pass that around internally. Easier semantics after a one-time conversion. No bridging worries. No unexpected copies. It seemed like a good idea at the time.</p>

<p>The problem is that using <code class="language-plaintext highlighter-rouge">UnsafeBufferPointer</code> everywhere tends to turn your code inside out. Where you used to say:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>updateCryptor(cryptor, data: data)
</code></pre></div></div>

<p>You now have to say:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>data.withUnsafeBufferPointer { updateCryptor(cryptor, data: $0) }
</code></pre></div></div>

<p>Two solutions present themselves. First you decide that you are very clever, and use the <code class="language-plaintext highlighter-rouge">UnsafeBufferPointer</code> constructor:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// Never do this
updateCryptor(cryptor, data: UnsafeBufferPointer(start: data, count: data.count))
</code></pre></div></div>

<p>Then @jckarter points out that by the time <code class="language-plaintext highlighter-rouge">updateCryptor</code> runs, there’s no promise that the <code class="language-plaintext highlighter-rouge">UnsafeBufferPointer</code> is still valid. ARC could destroy <code class="language-plaintext highlighter-rouge">data</code> before the statement even completes. (If you know that <code class="language-plaintext highlighter-rouge">data</code> is life-extended, then it is possible to know this will work, but it’s very unsafe, fragile, and hard to audit. Coding that way breaks everything Swift was trying to fix.)</p>

<p>So then you start creating function overloads to accept <code class="language-plaintext highlighter-rouge">Array</code> and <code class="language-plaintext highlighter-rouge">ArraySlice</code> and convert them into <code class="language-plaintext highlighter-rouge">UnsafeBufferPointer</code>, and you have even more duplicated code. And then you realize you want to accept <code class="language-plaintext highlighter-rouge">NSData</code> here, too, so you write an extension that adds <code class="language-plaintext highlighter-rouge">.withUnsafeBufferPointer()</code> to <code class="language-plaintext highlighter-rouge">NSData</code>, and now you have four versions of every function, and you realize you really should use a protocol instead. Brilliant!</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>protocol BufferType {
    func withUnsafeBufferPointer&lt;R&gt;(body: (UnsafeBufferPointer&lt;UInt8&gt;) throws -&gt; R) rethrows -&gt; R
}
</code></pre></div></div>

<p>This really feels like it’ll solve all these problems very elegantly. Except for this one problem. You want <code class="language-plaintext highlighter-rouge">[UInt8]</code> to be a <code class="language-plaintext highlighter-rouge">BufferType</code>, but you don’t want <code class="language-plaintext highlighter-rouge">[String]</code> to be a <code class="language-plaintext highlighter-rouge">BufferType</code>. And then you discover that while you can write extensions that only apply to <code class="language-plaintext highlighter-rouge">[UInt8]</code>, you can’t use those extensions to conform to a protocol. And that’s when the screaming starts. And then the barginning, and then the drinking.</p>

<p>When you get to the muttering, you came back and start building a <code class="language-plaintext highlighter-rouge">Buffer</code> class to wrap <code class="language-plaintext highlighter-rouge">Array</code>, <code class="language-plaintext highlighter-rouge">ArraySlice</code>, <code class="language-plaintext highlighter-rouge">NSData</code>, and even <code class="language-plaintext highlighter-rouge">CollectionType</code> to give it all a consistent interface. It’s ok, but it creates another “thing” for callers to deal with. In almost all cases, they have an <code class="language-plaintext highlighter-rouge">NSData</code>. There is almost no chance they had a <code class="language-plaintext highlighter-rouge">[UInt8]</code>. This is all just an extra layer for callers to deal with and to get in the way of the optimizer.</p>

<p>I want to remind you that all of this, all these many, many hours of struggle, were to avoid the simple <code class="language-plaintext highlighter-rouge">NSData</code> code that took two minutes to write, works great, and is pretty darn Swifty as long as you don’t define “Swifty” as “does not import Foundation.”</p>

<h2 id="whats-the-matter-with-nsdata">What’s the matter with NSData?</h2>

<p>So why did I resist using <code class="language-plaintext highlighter-rouge">NSData</code> anyway? Well, even though I believe the Foundation is absolutely a part of Swift, some of it isn’t <em>great</em> Swift. Notably <code class="language-plaintext highlighter-rouge">NSData</code> isn’t a <code class="language-plaintext highlighter-rouge">CollectionType</code>. But fixing that is <a href="https://gist.github.com/rnapier/da148690af63c401097d">pretty easy</a>.</p>

<p>End-to-end <code class="language-plaintext highlighter-rouge">NSData</code> also opened up some other opportunities for me, namely <code class="language-plaintext highlighter-rouge">dispatch_data</code>, which had threatened to be another can of worms with <code class="language-plaintext highlighter-rouge">[UInt8]</code>.</p>

<p>For some, none of this will matter. The vast majority of my problems come from trying to dodge unnecessary copies. Much of this is very simple if you’re willing to just copy the data all over the place. For many kinds of problems, that’s fine. Use whatever you like. The copy-on-write system is actually pretty awesome and for most problems you can certainly trust it.</p>

<p>But for those in my situation, where performance is a serious consideration in much of your code, you’re looking for predictability as much as speed, and data can be huge, my hope is we get a <code class="language-plaintext highlighter-rouge">Buffer</code> type (or <code class="language-plaintext highlighter-rouge">Data</code> or whatever) that acts as a bridge to <code class="language-plaintext highlighter-rouge">NSData</code>, supports <code class="language-plaintext highlighter-rouge">dispatch_data</code>, and plays nicely with stdlib. But until that comes, I think <code class="language-plaintext highlighter-rouge">NSData</code> is just fine.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Type-erasure in Stdlib]]></title>
    <link href="https://robnapier.net/type-erasure-in-stdlib"/>
    <updated>2015-10-06T19:05:13-04:00</updated>
    <id>https://robnapier.net/type-erasure-in-stdlib</id>
    <content type="html"><![CDATA[<p>When <a href="http://robnapier.net/erasure">last we talked about type erasure</a>, I described an easy way to build type erasures using closures. And I mentioned:</p>

<blockquote>
  <p>(While this works exactly like AnySequence, this isn’t how AnySequence is implemented. In my next post I’ll discuss why and how to implement type erasers like stdlib does.)</p>
</blockquote>

<p>At the time I thought I’d pretty well nailed it down, but every time I dug into it I found another little thing I’d missed, and it never seemed to end. And with stdlib open sourcing soon, you’ll all just be able to read this yourselves, so why embarrass myself getting it all wrong? Over time I kind of hoped you all had forgotten that comment and planned to move on to other things. But then I was <a href="https://twitter.com/My_kl/status/650796108789219328">busted by Michael Welch</a>, and so I had to finish the spelunking and here you go.
<!-- more --></p>

<p>So, <a href="https://github.com/rnapier/MyAnySequence">here</a> is my annotated implementation of <code class="language-plaintext highlighter-rouge">AnyGenerator</code> and <code class="language-plaintext highlighter-rouge">AnySequence</code> that I believe pretty closely matches Apple’s implementation in stdlib (minus some low-level optimizations in <code class="language-plaintext highlighter-rouge">AnySequence</code> that I’ll call out when we get there). I’ve named my versions of public symbols with a trailing underscore to differentiate from the Swift version. For private symbols (with leading underscore), I’ve used the same name Swift does.</p>

<p>All type information was determined using <code class="language-plaintext highlighter-rouge">:type lookup</code> in the Swift REPL. In a few places I checked the implementation with Hopper, but in most cases, once you have the types, the implementation is obvious. (There’s a deep lesson in there if you pay attention.)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RNCryptor V4]]></title>
    <link href="https://robnapier.net/rncryptor-v4"/>
    <updated>2015-10-04T12:38:36-04:00</updated>
    <id>https://robnapier.net/rncryptor-v4</id>
    <content type="html"><![CDATA[<p>After months of writing and rewriting, I am happy to finally announce <a href="https://github.com/RNCryptor/RNCryptor/releases/tag/RNCryptor-4.0.0-beta.1">RNCryptor 4 beta 1</a> in Swift.</p>

<p>RNCryptor 4 is a complete rewrite of RNCryptor for Swift 2 with full bridging support to Objective-C. It has a streamlined API, simpler installation, and improved internals. It continues to use the <a href="https://github.com/RNCryptor/RNCryptor-Spec/blob/master/RNCryptor-Spec-v3.md">v3 data format</a> and is fully interoperable with <a href="https://github.com/RNCryptor">other RNCryptor implementations</a>.
<!-- more --></p>

<p>For users desiring a fully Objective-C solution, <a href="https://github.com/RNCryptor/RNCryptor/releases/tag/RNCryptor-3.0.1">v3</a> is still available. I don’t currently plan to do significant new work on v3, but will consider it if there is strong interest. Going forward, I expect most OS X and iOS projects to be able to accept a mix of ObjC and Swift code. Objective-C continues to be a fully supported language in RNCryptor 4.</p>

<p>I plan to convert this to a final release in a week or so if no major issues are discovered.</p>

<p>I now move onto:</p>

<ul>
  <li>Continuing to prepare for <a href="http://www.dotswift.io">dotSwift</a>.</li>
  <li>Getting back to the blog.</li>
  <li>RNCryptor v5, which will finally update the data format to improve performance, security, and robustness. Much of the v4 design was specifically to make v5 easier to write.</li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Little Respect for AnySequence]]></title>
    <link href="https://robnapier.net/erasure"/>
    <updated>2015-08-04T15:42:00-04:00</updated>
    <id>https://robnapier.net/erasure</id>
    <content type="html"><![CDATA[<p>Once upon a time, when Swift was young, there were a couple of types called <code class="language-plaintext highlighter-rouge">SequenceOf</code> and <code class="language-plaintext highlighter-rouge">GeneratorOf</code>, and they could type erase stuff. “Type erase?” you may ask. “I thought we <em>loved</em> types.” We do. Don’t worry. Our types aren’t going anywhere. But sometimes we want them to be a little less…precise.</p>

<p>In Swift 2, our little type erasers got a rename and some friends. Now they’re all named “Any”-something. So <code class="language-plaintext highlighter-rouge">SequenceOf</code> became <code class="language-plaintext highlighter-rouge">AnySequence</code> and <code class="language-plaintext highlighter-rouge">GeneratorOf</code> became <code class="language-plaintext highlighter-rouge">AnyGenerator</code> and there are a gaggle of indexes and collections from <code class="language-plaintext highlighter-rouge">AnyForwardIndex</code> to <code class="language-plaintext highlighter-rouge">AnyRandomAccessCollection</code>.</p>

<p>So what are these type erasers? Let’s start with how to use one and we’ll work backwards to why.<!-- more --></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let seq = AnySequence([1,2,3])
</code></pre></div></div>

<p>This creates an <code class="language-plaintext highlighter-rouge">AnySequence&lt;Int&gt;</code>. It’s just a sequence of Ints that we can iterate over. Isn’t <code class="language-plaintext highlighter-rouge">[1,2,3]</code> also a sequence of Ints we can iterate over? Well, yeah. But it’s also explicitly an Array. And sometimes you don’t want to have to deal with that kind of implementation detail.</p>

<h2 id="who-needs-types-like-that">Who Needs Types Like That?</h2>

<p>Let’s consider a little more complicated case:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let xs = [1,2,3]
let ys = ["A","B","C"]
let zs = zip(xs.reverse(), ys.reverse())
// Zip2Sequence&lt;ReverseRandomAccessCollection&lt;Array&lt;Int&gt;&gt;, ReverseRandomAccessCollection&lt;Array&lt;String&gt;&gt;&gt;
</code></pre></div></div>

<p>That’s quite a type. Imagine it as the return type of a function:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>func reverseZip&lt;T,U&gt;(xs: [T], _ ys: [U]) -&gt; Zip2Sequence&lt;ReverseRandomAccessCollection&lt;[T]&gt;, ReverseRandomAccessCollection&lt;[U]&gt;&gt; {
  return zip(xs.reverse(), ys.reverse())
}
</code></pre></div></div>

<p>That’s insane. Let’s not do that. Not only is the type overwhelming, but it ties us to this particular implementation. We might want to refactor the code like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  return zip(xs, ys).reverse()
</code></pre></div></div>

<p>Then the return type would change to <code class="language-plaintext highlighter-rouge">[(T,U)]</code> and all the callers would have to be updated. Clearly we’re leaking too much information about our implementation. What’s the point of <code class="language-plaintext highlighter-rouge">reverseZip</code>? Is it to return a <code class="language-plaintext highlighter-rouge">Zip2Sequence&lt;...&gt;</code>? No. It’s to return a sequence of tuples. We want a type that means “a sequence of tuples.” Often we use <code class="language-plaintext highlighter-rouge">Array</code> for that, but there’s an even less restrictive way that doesn’t require making an extra copy: <code class="language-plaintext highlighter-rouge">AnySequence</code>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>func reverseZip&lt;T,U&gt;(xs: [T], _ ys: [U]) -&gt; AnySequence&lt;(T,U)&gt; {
    return AnySequence(zip(xs, ys).reverse())
}
</code></pre></div></div>

<p>Now we can keep our implementation details private. If we have some internal sequence type, we don’t have to share it with our callers. We just give them what they need and no more.</p>

<p>Notice that <code class="language-plaintext highlighter-rouge">AnySequence</code> is not a protocol. It’s a generic <code class="language-plaintext highlighter-rouge">struct</code> that wraps another sequence. You can’t use an <code class="language-plaintext highlighter-rouge">[Int]</code> in a place that expects an <code class="language-plaintext highlighter-rouge">AnySequence&lt;Int&gt;</code>. You still want to use <code class="language-plaintext highlighter-rouge">SequenceType</code> for parameters in most cases.</p>

<p>These “Any” type erasers also aren’t like <code class="language-plaintext highlighter-rouge">Any</code> and <code class="language-plaintext highlighter-rouge">AnyObject</code>, which are protocols that just “hide” the type. You can still <code class="language-plaintext highlighter-rouge">as!</code> an <code class="language-plaintext highlighter-rouge">AnyObject</code> back to its original type. <code class="language-plaintext highlighter-rouge">AnySequence</code> and its kin completely encapsulate the underlying data. You can’t get the original back. This creates a very strong abstraction layer and strengthens type safety by making <code class="language-plaintext highlighter-rouge">as!</code> casting impossible.</p>

<p><a href="http://www.openradar.me/radar?id=5528602095386624">The new names worry me a little</a> because they make it look like <code class="language-plaintext highlighter-rouge">AnyObject</code> and <code class="language-plaintext highlighter-rouge">AnySequence</code> are the same kind of thing when they’re not. But the new naming convention is definitely more flexible. You couldn’t have named the <code class="language-plaintext highlighter-rouge">AnyIndex</code> types using the old <code class="language-plaintext highlighter-rouge">...Of</code> convention. So, I’m getting used to the new names.</p>

<h2 id="chains-of-association">Chains of Association</h2>

<p>Hopefully by now you’re sold on why you’d want to use a type eraser. But would you ever want to build one? Let’s look at an example that comes up pretty often around associated types in protocols.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// An Animal can eat
protocol Animal {
    typealias Food
    func feed(food: Food)
}

// Kinds of Food
struct Grass {}
struct Worm {}

struct Cow: Animal {
    func feed(food: Grass) { print("moo") }
}

struct Goat: Animal {
    func feed(food: Grass) { print("bah") }
}

struct Bird: Animal {
    func feed(food: Worm) { print("chirp") }
}
</code></pre></div></div>

<p>So now let’s say we have a bunch of grass available and we’d like to feed it to some grass eaters. Seems easy:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>for animal in grassEaters {
    animal.feed(Grass())
}
</code></pre></div></div>

<p>Now we just have to create this array of grass eaters. Should be simple, right? Hmmm…</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let grassEaters = [Cow(), Goat()] // error: '_' is not convertible to 'Goat'
</code></pre></div></div>

<p>That’s a weird error. We probably just need to be explicit about the the type.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let grassEaters: [Animal] = [Cow(), Goat()]
// error: protocol 'Animal' can only be used as a generic constraint because it has Self or associated type requirements
</code></pre></div></div>

<p>We all know that error, don’t we? OK, let’s try generics.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let grassEaters: [Animal&lt;Grass&gt;] = [Cow(), Goat()]
// error: protocol 'Animal' can only be used as a generic constraint because it has Self or associated type requirements
</code></pre></div></div>

<p>Still? Oh right. You can’t specialize an associated type using generic syntax. That’s fine, we’ll just make the protocol generic.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>protocol Animal&lt;Food&gt; {
    func feed(food: Food)
}
// error: Statement cannot begin with a closure expression
</code></pre></div></div>

<p>Right, protocols can’t be generic. Type-safety is for chumps. Let’s go back to Objective-C.</p>

<p>…Or maybe type erasure is what we need. Let’s build <code class="language-plaintext highlighter-rouge">AnyAnimal</code>. There are several ways to do this, but the easiest in my opinion is with closures.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>struct AnyAnimal&lt;Food&gt;: Animal {
    private let _feed: (Food) -&gt; Void
    init&lt;Base: Animal where Food == Base.Food&gt;(_ base: Base) {
        _feed = base.feed
    }
    func feed(food: Food) { _feed(food) }
}
</code></pre></div></div>

<p>(While this works exactly like <code class="language-plaintext highlighter-rouge">AnySequence</code>, this isn’t how <code class="language-plaintext highlighter-rouge">AnySequence</code> is implemented. In my next post I’ll discuss why and how to implement type erasers like stdlib does.)</p>

<p>Now we can make <code class="language-plaintext highlighter-rouge">grassEaters</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let grassEaters = [AnyAnimal(Cow()), AnyAnimal(Goat())] // Type is [AnyAnimal&lt;Grass&gt;]
</code></pre></div></div>

<p>But we still get type safety if we try to incorrectly mix our animals:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let mixedEaters = [AnyAnimal(Cow()), AnyAnimal(Bird())]
// error: type of expression is ambiguous without more context
</code></pre></div></div>

<p>This kind of type eraser lets us convert a protocol with associated types into a generic type. That means we can put it in properties and return values and other places that we can’t use protocols directly. As you use more protocols in your Swift (and <a href="https://developer.apple.com/videos/wwdc/2015/?id=408">you should be</a>), I think this will become an important tool in your toolbelt.</p>

<p>So get out there and erase some over-specific types. Focus on the protocol, hide the implementation.</p>

<p><a href="https://gist.github.com/rnapier/03674b399e3bc517b9cd">And here’s the code for your amusement.</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Product or Process?]]></title>
    <link href="https://robnapier.net/product-or-process"/>
    <updated>2015-07-20T11:20:17-04:00</updated>
    <id>https://robnapier.net/product-or-process</id>
    <content type="html"><![CDATA[<p>Forgive a slight divergence. I’ll bring it back to software development before the end.</p>

<p>A friend of mine is an arborist. He takes care of a large forest, trimming and culling trees. He’s quite good at it and enjoys it, but he’s worried about job security. He thinks cabinet making would be a good career move. He likes to work with wood, and high-end cabinets are very expensive so there’s clearly a lot of money there. I’m a hobbyist woodworker, so we were talking about it.<!-- more --></p>

<hr />

<p>Me: So, what saws are you looking at?</p>

<p>Him: I have a Husqvarna 3120. That should be all I need.</p>

<p>Me: Husqvarna? Isn’t that a…chainsaw?</p>

<p>Him: It’s the best! I use it every day. I plan to do everything with it.</p>

<p>Me: It’s a good saw, sure, but… um… How are you going to join the pieces?</p>

<p>Him: Dovetail joints. I’ve heard those are best and you just have to cut notches. My chainsaw will make quick work of that.</p>

<p>Me: Dovetails have really tight tolerances. I can barely get them to work with a dovetail saw. Maybe you should start with pocket screws? They’re much easier and make great joints. A chainsaw…</p>

<p>Him: I’ve worked it all out. I modded this router table to hold my chainsaw upright so that’s just like a table saw. And I can make the other cuts freehand. I’m really good with a chainsaw. See, I already have a proof-of-concept.</p>

<p>Me: Um… that’s just a board with a notch in it.</p>

<p>Him: Yeah, but a cabinet is just a bunch of boards with notches. I’ll make some more and they should snap together.</p>

<p>Me: Cabinet tolerances are really tight. I mean, it’s not that hard to make a box, but making a full cabinet is difficult, even with proper tools. Why would you want to use some cobbled-together thing? That table looks terrifying.</p>

<p>Him: Look, I know chainsaws. I’m not going to go learn a bunch of new tools just to build cabinets. Wood is wood. Saws are saws. I’m using the saw I’m comfortable with. If I use the tools I know, I’m sure I can make really great cabinets.</p>

<p>Me: …</p>

<hr />

<p>In unrelated news, a lot of folks have asked if I’m excited that Go 1.5 can build iOS apps.</p>

<p>My wife’s background is art education. When you’re teaching art, she tells me, it’s important to remember whether you’re doing process art or product art in order to judge its success. Is the end result the goal, or how you got there? Am I trying to make the most beautiful painting I can, or am I trying to make a painting using only recycled materials? Does the audience need to know the process in order to appreciate the art, or does the end result stand on its own?</p>

<p>A lot of great hacks are process art. Can you run VMS on Linux? <a href="http://www.wherry.com/gadgets/retrocomputing/vax-simh.html">Sure you can!</a> Is that awesome? It is absolutely awesome. Is there any commercial reason to develop new VMS apps to run on Linux? Of course not. That would be ridiculous.</p>

<p>Is it fun to get the Go runtime working on surprising platforms? Sure, and the process may improve Go. That’s why process art is so common in art education. You put unnecessary restrictions on students so that they have to develop new skills that will be useful when they work on product art. “Draw without looking at your work” is an important exercise, but not usually how you create a masterpiece.</p>

<p>So let’s get to the “unnecessary restrictions” I’m talking about if you want to write excellent iOS apps in Go (or C# or JavaScript or….) I don’t want to spend too much time on the great memory management debate. Do modern concurrent garbage collection engines work well on dual-core, 1GB iPhones? I don’t know. I’m still hearing a lot of complaints about GC pauses on Lollipop with 2x the memory. It’s hard to imagine that Go GC on iOS is going to be faster and more memory efficient than Java GC on Android. But let’s put that question aside for the moment. Let’s assume there is a large genre of apps for which Go performance and memory usage is adequate, even excellent, on iOS devices. (This might even be true.)</p>

<p>The real question is “what’s the hard part of iOS development?”</p>

<p>If you think the answer is “Objective-C” then you don’t understand iOS development at all. Learning Objective-C is the <em>easiest</em> part of iOS development, doubly-so for anyone who is comfortable in a wacky (and awesome) language like Go. And when it finally settles down a bit, Swift will likely be easier to learn than Objective-C for Java-esque developers.</p>

<p>The sort-of hard piece of iOS development is UIKit, CloudKit, HomeKit, SpriteKit, SceneKit, HealthKit, WebKit, MapKit, StoreKit, GameplayKit, and another new Kit every release. It’s power management and backgrounding and handoff and watch integration and multitasking and adaptive fonts and auto layout and animations and app thinning. You can sometimes ignore those pieces, but they’re what separate barely acceptable apps from great apps. If your only goal is something that kind of works, fine. Anything can do that. Web apps can do that. But if you want to make a really great app, integrating with the platform is a must. And the platform is designed for Cocoa. And Cocoa is designed for ObjC and Swift. This stuff is hard when you’re using the tools Apple <em>intends</em> you to use. Working through translation layers is surgery with welding gloves.</p>

<p>And that brings us around to the <em>really</em> hard piece of iOS development. It changes. Constantly. Apple moves forward fast and they deprecate old APIs mercilessly. Clever work-arounds have short half-lives. You have to adapt every release, and find ways to be backward compatible while still compiling against the latest SDK. Once you’ve lived through a few releases of iOS, you discover how hard this piece can be even in ObjC, even when you’ve followed all the rules. I don’t envy anyone trying to deal with it through an unsupported layer. By the time anyone knows what the next iOS version breaks, the clock is already ticking. Whoever supports your extra layer has to fix their piece, and then you have to fix your piece. And with open iOS betas, your customers are already yelling.</p>

<p>So I may celebrate your chainsaw router table as a glorious (and terrifying) hack. But I’ll stick with my table saw for cabinets and my chainsaw for cutting up trees. A good crafter is capable with many tools, not just their favorite. And most iOS apps are about product, not process.</p>

<p><a href="http://www.elementscompiler.com/elements/silver/">Swift on Android?</a> I’ll take Java, thanks.</p>

<p>Lee Whitney has <a href="http://www.whitneyland.com/2015/07/xamarin-review-2015.html">an interesting take on this subject</a> from the C# side.</p>
]]></content>
  </entry>
  
</feed>
