🎉 End-of-year Sale! Save 25% when you subscribe today.

Protocol Witnesses: Part 1

Episode #33 • Oct 15, 2018 • Subscriber-Only

Protocols are a great tool for abstraction, but aren’t the only one. This week we begin to explore the tradeoffs of using protocols by highlighting a few areas in which they fall short in order to demonstrate how we can recover from these problems using a different tool and different tradeoffs.

Previous episode
Protocol Witnesses: Part 1
Next episode
Locked

Unlock This Episode

Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.

Sign in with GitHub

Introduction

Protocols are great! I use protocols. You use protocols. We all use protocols! They allows us to code to an interface rather than an implementation, and we’ve heard many times that this is a powerful idea. It gives you the ability to completely swap out implementations if you wanted, which is what many people do with their dependencies. They use live versions in production, but then substitute mock versions while testing.

However, protocols can’t possibly be the be-all and end-all of code reuse and extensibility in our Swift code. For one thing, they have a lot of problems that have to be dealt with! I’m sure everyone has come across the dreaded “Self or associated type requirements” error, and that’s always annoying. Also, protocols are quite rigid in that a type can conform to a given protocol in only one single way. Sometimes it’s completely valid and even technically correct to allow a type to conform to a protocol in multiple ways.

It turns out that basically every Swift protocol can be directly translated to a struct representation, and we’ve even done this process in a previous episode but we just didn’t dissect it. Doing this translation fixes a lot of the problems with protocols, but also introduces a few new quirks. Even cooler, this translation process is completely algorithmic. We can describe a set of steps that allows you to sit down and translate any protocol into a struct via a step-by-step process.

What’s a protocol?


References

  • Protocol-Oriented Programming in Swift
    Apple • Jun 16, 2015

    Apple’s eponymous WWDC talk on protocol-oriented programming:

    At the heart of Swift’s design are two incredibly powerful ideas

    protocol-oriented programming and first class value semantics. Each of these concepts benefit predictability, performance, and productivity, but together they can change the way we think about programming. Find out how you can apply these ideas to improve the code you write.

  • Modern Swift API Design
    Apple • Jan 2, 2019

    As of WWDC 2019, Apple no longer recommends that we “start with a protocol” when designing our APIs. A more balanced approach is discussed instead, including trying out concrete data types. Fast forward to 12:58 for the discussion.

    Note

    Every programming language has a set of conventions that people come to expect. Learn about the patterns that are common to Swift API design, with examples from new APIs like SwiftUI, Combine, and RealityKit. Whether you’re developing an app as part of a team, or you’re publishing a library for others to use, find out how to use new features of Swift to ensure clarity and correct use of your APIs.

  • Protocols with Associated Types
    Alexis Gallagher • Dec 15, 2015

    This talk by Alexis Gallagher shows why protocols with associated types are so complicated, and tries to understand why Swift chose to go with that design instead of other alternatives.

  • Protocol Oriented Programming is Not a Silver Bullet
    Chris Eidhof • Nov 24, 2016

    An old article detailing many of the pitfalls of Swift protocols, and how often you can simplify your code by just using concrete datatypes and values. Chris walks the reader through an example of some networking API library code, and shows how abstracting the library with protocols does not give us any tangible benefits, but does increase the complexity of the code.

  • Value-Oriented Programming
    Matt Diephouse • Jul 29, 2018

    Matt gives another account of protocol-oriented programming gone awry, this time by breaking down the famous WWDC talk where a shape library is designed using protocols. By rewriting the library without protocols Matt ends up with something that can be tested without mocks, can be inspected at runtime, and is more flexible in general.

  • Scrap your type classes
    Gabriella Gonzalez • May 2, 2012

    Haskell’s notion of protocols are called “type classes,” and the designers of Swift have often stated that Swift’s protocols took a lot of inspiration from Haskell. This means that Haskellers run into a lot of the same problems we do when writing abstractions with type classes. In this article Gabriella Gonzalez lays down the case for scrapping type classes and just using simple datatypes.

  • Haskell Antipattern: Existential Typeclass
    Luke Palmer • Jan 24, 2010

    A Haskell article that demonstrates a pattern in the Haskell community, and why it might be an anti-pattern. In a nutshell, the pattern is for libraries to express their functionality with typeclasses (i.e. protocols) and provide Any* wrappers around the protocol for when you do not want to refer to a particular instance of that protocol. The alternative is to replace the typeclass with a simple concrete data type. Sound familiar?

  • Protocol Witnesses: App Builders 2019
    Brandon Williams • May 3, 2019

    Brandon gave a talk about “protocol witnesses” at the 2019 App Builders conference. The basics of scraping protocols is covered as well as some interesting examples of where this technique really shines when applied to snapshot testing and animations.

    Note

    Protocol-oriented programming is strongly recommended in the Swift community, and Apple has given a lot of guidance on how to use it in your everyday code. However, there has not been a lot of attention on when it is not appropriate, and what to do in that case. We will explore this idea, and show that there is a completely straightforward and mechanical way to translate any protocol into a concrete datatype. Once you do this you can still write your code much like you would with protocols, but all of the complexity inherit in protocols go away. Even more amazing, a new type of composition appears that is difficult to see when dealing with only protocols. We will also demo a real life, open source library that was originally written in the protocol-oriented way, but after running into many problems with the protocols, it was rewritten entirely in this witness-oriented way. The outcome was really surprising, and really powerful.

Downloads

Get started with our free plan

Our free plan includes 1 subscriber-only episode of your choice, access to 64 free episodes with transcripts and code samples, and weekly updates from our newsletter.

View plans and pricing