This is my research notebook. I'm an OSX / iOS indie developer. After 8 years of Objective-C I really enjoy Swift nowadays. Trying to publish all my research on Development, Swift & other technologies here.

Thu, 24 Jan 2019 #

An interactive Git Status client, written in C


Gitsi On GitHub Youtube Video

Over Christmas I decided on a whim to solve a workflow-related problem that I've had for some time and to also go back and write a small-scale project in C. The result is Gitsi a small, lightweight, interactive git status client that offers fast shortcuts to quickly manage the git status output. Let me go back to the actual problem I had.

1 Using Git on the Commandline

Over the years I've tried and used many different git clients. SourceTree, GitUp, Gitk, Magit, to name a few. Magit (a Git client build into Emacs) is the one I still use the most, but over the years I've more and more moved towards plain git on the terminal for most of my daily activities. However, one thing always bugged me: If I have an output from git status (say the following one):

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)


Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   component_stats.db
        modified:   q.sql

Untracked files:
  (use "git add <file>..." to include in what will be committed)


Then if I want to add the two untracked files and the q.sql to the index (in order to commit them) I'd have to write:

git add documentation/
git add pi_design/
git add q.sql

That's a lot of typing. Usually I go about copy pasting with the mouse. That also takes forever. Surely using a git GUI tool (like SourceTree) is much faster but as I don't need it for any of the other tasks I usually do, I'd need to start it first, which also takes forever. What I envisioned was an easy way to add, stage, unstage files in the git index, workspace and untracked files. Bonus points for also allowing git checkout -- to remove changes to a specific file.

I know there're tools for that (such as tig) but I wanted something that only did one thing, status management. No logging, no pushing or pulling, etc. This felt to me like a great opportunity to write a small scale C project, something I hadn't done for at least more than 10 years.

2 Gitsi

This is how gitsi was born. Have a look at the project if you're interested, it offers a nice handful of features such as all of the above plus: VIM Keybindings, filtering, diffing, interactive git add and more.

Here's a short video that shows it in action

3 Writing in C

As a iOS developer I've had my fair share of Objective-C, however all the nice abstractions that Apple put in place actually mean that usually I don't really touch C code. So, writing something bigger in C was really interesting when comparing it to developing something in Swift (doh, obviously).

It relies on two libraries:

  • libgit2: The interface to git. Interestingly git (the commandline tool) and libgit2 are separate entities. Meaning git does not use libgit. This means that for some things that git does, there is no easy equivalent in libgit. This makes some things very hard.
  • ncurses: This is the library to use when developing TUI (terminal UI) applications. It allows you to move the cursor around in the terminal, color it, draw windows, etc.

3.1 The fun parts

  • Compile times were beyond beautiful
  • The limited featureset of the language made it surprisingly fun to work on a project of this size. There's no questioning which abstraction to use, there's usually only one that fits. If there're more, they require more indepth knowledge of the language.
  • This is not particular to C, but the reactive approach of writing a TUI app by just rendering over a mainloop (also like most games) feels very refreshing compared to normal iOS work (obvious comparison to React, etc)
  • Getting it to work on a different platform (Linux) was also kinda easy, though I struggled more with it than I would have expected. In particular there're several useful functions that are not part of C99 (the 99 C standard). Using them requires the correct compile flag (-std=gnu11). However, some functions are also not part of the C standard, but specific GNU extensions, though they're also supported on all the platforms I care about. Using these requires adding a #define _GNU_SOURCE at the top of your source file. However, not on macOS, but on Linux. This was tricky to figure out.

3.2 The less fun parts

  • Memory management. This was totally expected, but it consumed more time than I'd have expected. Thankfully, valgrind is a great tool to find these issues. Sadly, valgrind seems to not run on macOS right now, so I ran it via Docker. That worked great though. I had a lot of small issues that seem to be (mostly) fixed now. This experience alone makes me so grateful for Swift's Arc and Rust's Borrow Checker.
  • Documentation. This was terrible. The libgit documentation is mostly ok, but for the C stdlib and epecially ncurses, the documentation is just awful. Since they all differ platform by platform, implementation by implementation, there's no one reference. Sometimes it would take me forever to just figure out what the parameters to a certain function would do. Getting this done involved a lot of googling.
  • Lack of tooling suite. Sure, almost every editor supports C, but almost everything in tooling requires choices, research and pain. There's no one package manager / ecosystem. How to handle building, there're a ton of build systems, how to handle tests, there're a ton of solutions. Since everything is so free and open, everything is also a mess. It is probably much easier when you're working on a pre-existing, pre-defined project, but there's a huge overhead of things just to get started. I tried to keep it as simple as possible. System Package Manager (homebrew / apt-get), vim, cmake and no tests.

4 Using it with Xcode

Working on a project like this from Xcode works surprisingly well. I set up an Xcode project, added the required libraries (ncurses and libgit) imported the main.c file and I could compile it. Debugging was a wee bit more work. Since Xcode can't run ncurses executables (i.e. it can't run them in a terminal) we have to tell Xcode to compile the app and then wait for the process to start and then to attach to it. After that, I can head to a terminal and run the just-compiled app and then Xcode will attach to it and all the breakpoints etc work. It is a wee bit more cumbersome but works fine. I had to introduce a particular command line flag though that makes sure that attaching via Xcode doesn't break things.

5 Testing

There're no tests. Yet. I've started on the necessary prerequisites to run integration tests but I wanted to release it first. The idea is to start the binary in a special mode and give it a string of tasks (i.e. go down 2 lines, do a git add, go up one line, etc) and then make sure that the end result is what's expected.

6 Recap

This was a fun project, but now I'm also done with C for the rest of this year (except for small additions to gitsi, of course). I'm already longing to do something in Swift or Rust again.

If you read this far, you should follow me (@terhechte)
on Twitter

    Thu, 3 April 2018 #

    Expanding Swift's Reach

    I guess we can all agree that Swift is a beautiful programming language that manages to hit the sweet spot in terms of simplicity and complexity. It could theoretically become one of the major languages of the future. Currently though, Swift's usage is more or less constrained to the Apple development domain (plus a few extensions such as server-side Swift or the recently announced Swift for Tensorflow).

    My goal for Swift has always been and still is total world domination. It’s a modest goal

    • Chris Lattner

    With Swift 4.1's new generic features and the upcoming ABI stability in Swift 5, it feels like Swift slowly reaches a point that would allow it to move beyond the Apple domain. In this post I'd like to discuss what I see as one of the issues holding it back from a broader adoption. Specifically, the one issue that can be solved by us as a community while most of the other issues are already being worked on.

    I'd also like have a brief look at Swift's competition in this space. I.e. other languages that also aspire to become a general purpose language for all the domains that C++ currently encompasses - and maybe more 1. By observing their take on the issue we can see where Swift stands in comparison, and what we can do.

    1 System Packages

    Swift has a very healthy open source community with a good amount of fantastic, well-written, and useful packages. However, the nature of Swift's current primary domain constrained these packages almost exclusively to iOS (and much less, macOS) UI libraries. There're a dozen UI Animation libraries, UI layout libraries, UI element frameworks, UI helpers and, of course, JSON parsers. Most of those packages don't even run on Linux as there is no UIKit / AppKit. Of course, there are also several web frameworks like Vapor or Kitura, and they're doing a fantastic job of extending Swift's into the web development realm.

    However, contrary to popular opinion, companies do a lot more on Linux than just running webservers. As we will see in a brief moment, other languages offer a lot of system management, administration, or general development tools and libraries that make no sense for iOS or macOS app development but are tremendously important for systems- or web-development. I.e. databases and their administration, system file management, process management and administration, log and analytics collection, container administration, deployment tooling, or even blockchain tooling - just to name a few.

    In line with Swift's 4.1 release, there was a thread on Hacker News discussing the language. I've read the entire thread multiple times due to the fact that the answers were really interesting. What stood out to me was the following comment:

    The set of libraries and supported OSes is a tiny dot comparable with the Go and Rust. … If we start listing the kind of libraries used in distributed applications, database backends, Swift has hardly none of them.

    So lets have a look at the others.

    2 Competitors

    The field of programming language development has seen a lot of new competitors over the last couple of years. Naturally, we (that is, you dear reader, and me) will probably not agree on which of these languages we do or don't consider as true competition for Swift. That is, here're - in no particular order - my personal picks based on gut feelings.

    Also, the opinions below are loosely held. So if you're a fan of any of the languages I'm about to mention and my description feels wrong to you and you're burning with a desire for venegance and about to grab your pitchfork and head to Twitter.. please don't, I'm just a normal guy with a loosely held opinion who most certainly is wrong about a lot of things. Instead, use this energy to pursue the question of how it came to be that I'm misinformed on this particular topic and try to help to improve on that front.

    2.1 Go

    Go has been available much longer than Swift, enjoys strong usage in the realm of system tools, is hardly used for GUI applications, doesn't provide more modern language features such as tagged unions, generics, or functional programming constructs. It is easy to learn, fast, uses a Garbage Collector and the resulting binaries are lightweight in terms of memory. The garbage collector make it somewhat tricky to use Go for embedded development or even Webassembly.

    The good performance, simplicity of the language and low memory footprint lead to the development of a lot of system tools & libraries, such as: Grafana, Kubernetes, CoreOS-etcd, Go-Ethereum, CockroachDB, Hub, Terraform and many, many others. Have a look at this list just to observe how many libraries there are for any use case possibly imaginable.

    In short, if you want to develop anything system-based, almost all packages you might need as dependencies are readily available.

    2.2 Kotlin

    Kotlin, basically the Swift for Android is a language that feels and looks a lot like Swift but is - under the hood - quite different. The JVM foundation of Kotlin forces it to utilize a much stronger usage of reference types vs. value types. Like Go, the Garbage Collector makes embedded & systems development a challenge, however there is Kotlin-Native which will make this more feasible in the future. It builds with LLVM, supports embedded platforms, Webassembly, and much more. Kotlin can also be compiled to Javascript, and Kotlin-Native even allows buliding Frameworks for iOS apps.

    Kotlin could also become a big language in the future but is currently held back by the same mechanics that are also holding back Swift: Almost all available open source libraries are primarily for Android development (i.e. UI, etc). While Kotlin native solves the issues that a pure JVM language would have, I have no idea how performant and lightweight Kotlin native could actually become (i.e. Compared to C++ or Swift, especially for things like embedded development, complex systems development, or Webassembly).

    2.3 Rust

    Rust is an interesting language. Actually so interesting that I spend the last couple of months slowly learning it. In many ways it is very similar to Swift - but harder (but this is a topic for a future blog post). it feels like the two languages started out diametrically opposed from each other: Swift started out as an (mostly) easy to learn language with a easy-to-grasp feature set which is slowly adding more complex features. Rust started out as a complex language which is slowly adding simpler abstractions or better error messages to make it more approachable for beginners. Given that both languages have a very similar syntax it wouldn't surprise me when, at some point in the future, both languages converge to a point of high similarity in terms of features and simplicity / complexity. However, currently, Rust offers a couple of very attractive features hidden behind a more complex learning experience:

    A much better cross-platform story, a hard but rewarding memory management story (i.e. lifetimes / ownership) that is thankfully also partially coming to Swift in the future, support for Webassembly (i.e. you can write frontend apps in Rust), and the beginnings of a really good foundation of packages to allow users to quickly get started on new projects. While it does not offer the same amount of high-profile projects like Go, there're already a couple of promising projects (CoreUtils, RedoxOS, TikV, Vagga, Servo, Parity), but more importantly, there are many libraries for interaction with third party dependencies. Have a look at this list.

    2.4 Others

    There're also D, Nim, Chrystal, Elixir, TypeScript, and obviously C++ itself but this post is already long enough as it is.

    3 What can we see

    Swift currently falls short in the area of system packages. This is also a chicken-egg problem:

    As long as there are not enough system packages, an interested developer will try out Swift, but will not find a package for his favorite database. Not interested in porting a database package just for the sake of writing a simple example app, he will back off and never start to enjoy the language enough to start submitting his own system packages.

    To me it feels like we need to improve our system package / library game. It would certainly be nice if we had something like Kubernetes written in Swift, but in order for such a project to emerge, we need a good set of base libraries that are useful for general systems development. Libraries for tasks or third party services in the following domains (also, some of those domains may have packages already, but that doesn't mean we need more):

    • Authentication
    • Caching
    • Concurrency
    • Cloud Providers
    • Command Line Argument Parsing
    • Command Line UI
    • Command Line Editors
    • Compression
    • Computations (i.e. BLAS)
    • Cryptography
    • Databases
    • Data Processing
    • Data Structures
    • Data Visualization
    • Date and Time
    • Distributed Systems
    • Email
    • Encoding & Decoding
    • Filesystems
    • Image Processing
    • Machine Learning
    • Parsing
    • Text Processing
    • Virtualization

    In order to become a valid general purpose language on Non-Apple operating systems, I think, Swift needs to offer a healthy ecosystem of useful system packages on all platforms.

    4 So, what can you do

    4.1 Write libraries

    Before you decide to write the 150th JSON parser, Animation library, custom switch button, or collection view / table view abstraction, consider writing a fully working cross platform system library. If you can't come up with an idea head over to Rust or Go and see what they have to offer.

    4.2 Rewrite Existing C libraries

    For certain use cases, Swift does offer libraries but only via a small shism to an underlying C implementation. While that does get the job done, it introduces a very unsafe language into the mix, something we should only need to do in use cases where performance is absolutely critical. So, if you can't think of anything you'd want to write, maybe write a pure-swift implementation of something you already use. That's also a great opportunity for learning more C and in turn loving Swift even more ;-)

    4.3 Care about Linux

    I recently wrote a small application in Vapor and for that I needed a couple of additional dependencies (i.e. for time calculations) and almost all existing libraries were iOS / macOS only. If you already work on something that could be cross platform (due to no UIKit / AppKit dependencies) try to go the extra step of testing it on Swift Linux.

    This might also be easier than it sounds. There's a readily-available docker image for Swift 4.1, so you can just run that in order to test your code.2. Alternatively, you can run Virtualbox if you'd rather have a full running VM.

    4.4 Support Swift Package Manager

    If you have a library already, try to always support the Swift Package Manager in addition to CocoaPods and Carthage.

    4.5 Work on Foundation

    Another thing that is still difficult is that Swift for Linux's Foundation library is a re-implementation of iOS/macOS foundation and therefore still has unimplemented features and (especially tricky) bugs. This means that code you write on your Mac in Xcode might run great, but it will crash on Linux because of a Linux-Only foundation bug. Making Foundation for Linux better is another great task to work on in order to improve Swift's reach.

    The easiest starter for this is to head over to the Swift Jira and search for Foundation bugs.

    4.6 Help out Foundation

    If you don't have the time or are not interested in working on Swift Foundation, you can still help out by using it / testing it on Linux and submitting bug reports. The more people use it, the more stable it will become.

    4.7 Help the Linux editing experience

    Linux users won't have Xcode, so they'll be using Atom or Emacs or Vim or VSCode. There're already multiple projects that offer Swift support for these editors, but it feels like we can also improve on this front. If you have some cycles to spare, play around with these projects and your favorite non-Xcode editor, see if things work as expected, otherwise create issues or (even better!) try to actively fix them ;)

    4.8 Try Swift in San Jose

    If you happen to be in San Jose during this years WWDC, there's a great opportunity for you to learn something, meet interesting people, and help out Swift: The Try Swift San Jose.

    …your chance to contribute to Swift. Join a panel of Swift Open Source contributors for a discussion about the latest news on the Swift open source project, then contribute to Swift Evolution yourself with the help of community mentors!

    Check it out.

    5 I should be doing this

    I haven't had much time to do any open source work in the past 1.5 years because I was busy working on my own (closed source) project, but I really want to work on open source Swift code again. I really like Swift, it is a great language, and helping it to (hopefully) succeed feels like the best pasttime to have. If you feel the same, feel free to share this article.

    Also, for any discussion on this article, head to Twitter.


    I.e. WebAssembly
    I'm trying to write another blog post that explains this in much more detail

    If you read this far, you should follow me (@terhechte)
    on Twitter

      Wed, 10 Jan 2018 #

      Useful Optional Extensions

      Optionals are a staple of Swift. I guess everybody will agree that they are a huge boon insofar as they force us to properly handle edge cases. The Optional language feature alone removes a whole category of bugs from the development process.

      However, the API surface of Swift's optional is rather limited. The Swift documentation lists just a couple of methods / properties on Optional - if we ignore customMirror and debugDescription:

      var unsafelyUnwrapped: Wrapped { get } 
      func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U? 
      func flatMap<U>(_ transform: (Wrapped) throws -> U?) rethrows -> U? 

      The reason why optionals are still very useful even though they have such a small amount of methods is that the Swift syntax makes up for it via features such as optional chaining, pattern matching, if let or guard let. In some situations, though, this manifests itself in unnecessary line noise. Sometimes, a very succinct method will let you express a concept in one short line of code instead of multiple lines of combined if let statements.

      I've sifted through Swift Projects on Github as well as the optional implementations of other languages such as Rust, Scala, or C# in order to find a couple of useful additions to Optional. Below are 14 useful Optional extensions. I'll describe them by category and then give a couple of examples per category. Finally, I'll write a more involved example that uses several extensions at once.

      1 Emptiness

      extension Optional {
          /// Returns true if the optional is empty
          var isNone: Bool {
      	return self == .none
          /// Returns true if the optional is not empty
          var isSome: Bool {
      	return self != .none

      Those are the most basic additions to the optional type. The implementation could also use a switch pattern match instead, but the nil comparison is much shorter. What I like about these additions is that they move the concept of an empty optional being nil away from your code. This might just as well be an implementation detail. Using optional.isSome feels much cleaner and less noisy than if optional == nil:

      // Compare
      guard leftButton != nil, rightButton != nil else { fatalError("Missing Interface Builder connections") }
      // With
      guard leftButton.isSome, rightButton.isSome else { fatalError("Missing Interface Builder connections") }

      2 Or

      extension Optional {
          /// Return the value of the Optional or the `default` parameter
          /// - param: The value to return if the optional is empty
          func or(_ default: Wrapped) -> Wrapped {
      	return self ?? `default`
          /// Returns the unwrapped value of the optional *or*
          /// the result of an expression `else`
          /// I.e. optional.or(else: print("Arrr"))
          func or(else: @autoclosure () -> Wrapped) -> Wrapped {
      	return self ?? `else`()
          /// Returns the unwrapped value of the optional *or*
          /// the result of calling the closure `else`
          /// I.e. optional.or(else: { 
          /// ... do a lot of stuff
          /// })
          func or(else: () -> Wrapped) -> Wrapped {
      	return self ?? `else`()
          /// Returns the unwrapped contents of the optional if it is not empty
          /// If it is empty, throws exception `throw`
          func or(throw exception: Error) throws -> Wrapped {
      	guard let unwrapped = self else { throw exception }
      	return unwrapped
      extension Optional where Wrapped == Error {
          /// Only perform `else` if the optional has a non-empty error value
          func or(_ else: (Error) -> Void) {
      	guard let error = self else { return }

      Another abstraction on the isNone / isSome concept is being able to specify instructions to be performed when the invariant doesn't hold. This saves us from having to write out if or guard branches and instead codifies the logic into a simple-to-understand method.

      This concept is so useful, that it is defined in three distinct functions.

      2.1 Default Value

      The first one returns the wrapped value of the optional or a default value:

      let optional: Int? = nil
      print(optional.or(10)) // Prints 10

      2.2 Default Closure

      The second one is very similar to the first one, however it allows to return a default value from a closure instead.

      let optional: Int? = nil
      optional.or(else: secretValue * 32) 

      Since this uses the @autoclosure parameter we could actually use just the second or implementation. Then, using a just a default value would automatically be converted into a closure returning the value. However, I prefer having two separate implementations as that allows users to also write closures with more complex logic.

      let cachedUserCount: Int? = nil
      return cachedUserCount.or(else: {
         let db = database()
         guard db.failures.isEmpty else { return 0 }
         return db.amountOfUsers

      A really nice use case for or is code where you only want to set a value on an optional if it is empty:

      if databaseController == nil {
        databaseController = DatabaseController(config: config)

      This can be replaced with the much nicer:

      databaseController = databaseController.or(DatabaseController(config: config)

      2.3 Throw an error

      This is a very useful addition as it allows to merge the chasm between Optionals and Error Handling in Swift. Depending on the code that you're using, a method or function may express invalid behaviour by returning an empty optional (imagine accessing a non-existing key in a Dictionary) or by throwing an Error. Combining these two oftentimes leads to a lot of unnecessary line noise:

      func buildCar() throws -> Car {
        let tires = try machine1.createTires()
        let windows = try machine2.createWindows()
        guard let motor = externalMachine.deliverMotor() else {
          throw MachineError.motor
        let trunk = try machine3.createTrunk()
        if let car = manufacturer.buildCar(tires, windows,  motor, trunk) {
          return car
        } else {
          throw MachineError.manufacturer

      In this example, we're building a car by combining internal and external code. The external code (external_machine and manufacturer) choose to use optionals instead of error handling. This makes the code unnecessary complicated. Our or(throw:) function makes this much more readable:

      func build_car() throws -> Car {
        let tires = try machine1.createTires()
        let windows = try machine2.createWindows()
        let motor = try externalMachine.deliverMotor().or(throw: MachineError.motor)
        let trunk = try machine3.createTrunk()
        return try manufacturer.buildCar(tires, windows,  motor, trunk).or(throw: MachineError.manufacturer)

      2.4 Handling Errors

      The code from the Throw an error section above becomes even more useful when you include the following free function that was proposed by Stijn Willems on Github. Thanks for the suggestion!

      func should(_ do: () throws -> Void) -> Error? {
          do {
      	try `do`()
      	return nil
          } catch let error {
      	return error

      This free function (alternatively, you could make it a class method on optional) will perform a do {} catch {} block and return an error if and only if the closure `do` resulted in an error. Take, the following Swift code as an example:

      do {
        try throwingFunction()
      } catch let error {

      This is one of the basic tennets of error handling in Swift, and it introduces quite a lot of line noise. With the free function above, you can reduce it to this simple on-liner:

      should { try throwingFunction) }.or(print($0))

      I feel that there're many situations where such a one-liner for error handling would be very beneficient.

      2.5 Map

      As we saw above, map and flatMap are the only methods that Swift offers on Optionals. However, even those can be improved a bit to be more versatile in many situations. There're two additional variations on map that allow defining a default value similar to how the or variants above are implemented:

      extension Optional {
          /// Maps the output *or* returns the default value if the optional is nil
          /// - parameter fn: The function to map over the value
          /// - parameter or: The value to use if the optional is empty
          func map<T>(_ fn: (Wrapped) throws -> T, default: T) rethrows -> T {
      	return try map(fn) ?? `default`
          /// Maps the output *or* returns the result of calling `else`
          /// - parameter fn: The function to map over the value
          /// - parameter else: The function to call if the optional is empty
          func map<T>(_ fn: (Wrapped) throws -> T, else: () throws -> T) rethrows -> T {
      	return try map(fn) ?? `else`()

      The first one will allow you to map the contents of an optional to a new type T. If the optional is empty, you can define a default value that should be used instead:

      let optional1: String? = "appventure"
      let optional2: String? = nil
      // Without
      print({ $0.count }) ?? 0)
      print({ $0.count }) ?? 0)
      // With 
      print({ $0.count }, default: 0)) // prints 10
      print({ $0.count }, default: 0)) // prints 0

      The changes are minimal, but we're moving away from having to use the ?? operator and can instead express the operation more clearly with the default keyword.

      The second variant is very similar. The main difference is that it accepts (again) a closure returning value T instead of value T. Here's a brief example:

      let optional: String? = nil
      print({ $0.count }, else: { "default".count })

      3 Combining Optionals

      This category contains four functions that allow you to define relations between multiple optionals.

      extension Optional {
          /// Tries to unwrap `self` and if that succeeds continues to unwrap the parameter `optional`
          /// and returns the result of that.
          func and<B>(_ optional: B?) -> B? {
      	guard self != nil else { return nil }
      	return optional
          /// Executes a closure with the unwrapped result of an optional.
          /// This allows chaining optionals together.
          func and<T>(then: (Wrapped) throws -> T?) rethrows -> T? {
      	guard let unwrapped = self else { return nil }
      	return try then(unwrapped)
          /// Zips the content of this optional with the content of another
          /// optional `other` only if both optionals are not empty
          func zip2<A>(with other: Optional<A>) -> (Wrapped, A)? {
      	guard let first = self, let second = other else { return nil }
      	return (first, second)
          /// Zips the content of this optional with the content of another
          /// optional `other` only if both optionals are not empty
          func zip3<A, B>(with other: Optional<A>, another: Optional<B>) -> (Wrapped, A, B)? {
      	guard let first = self,
      	      let second = other,
      	      let third = another else { return nil }
      	return (first, second, third)

      These four functions all share that they take an additional optional as a parameter and return another optional value. However, they're all quite different in what they achieve.

      3.1 Dependencies

      and<B>(_ optional) is useful if the unpacking of an optional is only required as a invariant for unpacking another optional:

      // Compare
      if user != nil, let account = userAccount() ...
      // With
      if let account = user.and(userAccount()) ...

      In the example above, we're not interested in the unwrapped contents of the user optional. We just need to make sure that there is a valid user before we call the userAccount function. While this relationship is kinda codified in the user != nil line, I personally feel that the and makes it more clear.

      3.2 Chaining

      and<T>(then:) is another very useful function. It allows to chain optionals together so that the output of unpacking optional A becomes the input of producing optional B. Lets start with a simple example:

      protocol UserDatabase {
        func current() -> User?
        func spouse(of user: User) -> User?
        func father(of user: User) -> User?
        func childrenCount(of user: User) -> Int
      let database: UserDatabase = ...
      // Imagine we want to know the children of the following relationship:
      // Man -> Spouse -> Father -> Father -> Spouse -> children
      // Without
      let childrenCount: Int
      if let user = database.current(), 
         let father1 = database.father(user),
         let father2 = database.father(father1),
         let spouse = database.spouse(father2),
         let children = database.childrenCount(father2) {
        childrenCount = children
      } else {
        childrenCount = 0
      // With
      let children = database.current().and(then: { database.spouse($0) })
           .and(then: { database.father($0) })
           .and(then: { database.spouse($0) })
           .and(then: { database.childrenCount($0) })

      There're a lot of improvements when using the version with and(then). First of all, you don't have to come up with superfluous temporary variable names (user, father1, father2, spouse, children). Second, we clearly have less code. Also, using the or(0) instead of a complicated let childrenCount is so much easier to read.

      Finally, the original Swift example can easily lead to logic errors. You may not have noticed, but there's a bug in the example. When writing lines like that, copy paste errors can easily be introduced. Do you see the error?

      Yeah, the children property should be created by calling database.childrenCount(spouse) but I wrote database.childrenCount(father2) instead. It is difficult to spot errors like that. The and(then:) example makes it much easier because it always relies on the same variable name $0.

      3.3 Zipping

      This is another variation on an existing Swift concept. The zip method on optional will allow us to combine multiple optionals and unwrap them together or not at all. I've just provided implementations for zip2 and zip3 but nothing prevents you from going up to zip22 (Well, maybe sanity and compiler speed).

      // Lets start again with a normal Swift example
      func buildProduct() -> Product? {
        if let var1 = machine1.makeSomething(),
          let var2 = machine2.makeAnotherThing(),
          let var3 = machine3.createThing() {
          return finalMachine.produce(var1, var2, var3)
        } else {
          return nil
      // The alternative using our extensions
      func buildProduct() -> Product? {
        return machine1.makeSomething()
           .zip3(machine2.makeAnotherThing(), machine3.createThing())
           .map { finalMachine.produce($0.1, $0.2, $0.3) }

      Less code, clearer code, more beautiful code. However, as a downside, this code is also more involved. The reader has to know and understand zip in order to easily grasp it.

      3.4 On

      extension Optional {
          /// Executes the closure `some` if and only if the optional has a value
          func on(some: () throws -> Void) rethrows {
      	if self != nil { try some() }
          /// Executes the closure `none` if and only if the optional has no value
          func on(none: () throws -> Void) rethrows {
      	if self == nil { try none() }

      These two short methods will allow you to perform side effects if an optional is empty or not. In contrast to the already discussed methods, these ignore the contents of the optional. So on(some:) will only execute the closure some if the optional is not empty but the closure some will not get the unwrapped contents of the optional.

      /// Logout if there is no user anymore
      self.user.on(none: { AppCoordinator.shared.logout() })
      /// self.user is not empty when we are connected to the network
      self.user.on(some: { AppCoordinator.shared.unlock() })

      3.5 Various

      extension Optional {
          /// Returns the unwrapped value of the optional only if
          /// - The optional has a value
          /// - The value satisfies the predicate `predicate`
          func filter(_ predicate: (Wrapped) -> Bool) -> Wrapped? {
      	guard let unwrapped = self,
      	    predicate(unwrapped) else { return nil }
      	return self
          /// Returns the wrapped value or crashes with `fatalError(message)`
          func expect(_ message: String) -> Wrapped {
      	guard let value = self else { fatalError(message) }
      	return value

      3.5.1 Filter

      This is a simple method which works like an additional guard to only unwrap the optional if it satisfies a predictate. Here's an example. Imagine we want to upgrade all our old users to a premium account for sticking with us for a long time:

      // Only affect old users with id < 1000
      // Normal Swift
      if let aUser = user, < 1000 { aUser.upgradeToPremium() }
      // Using `filter`
      user.filter({ $ < 1000 })?.upgradeToPremium()

      Here, user.filter feels like a much more natural implementation. Also, it only implements what already exists for Swift's collections.

      3.5.2 Expect

      This is one of my favorites. Also, I shamelessly stole it from Rust. I'm trying very hard to never force unwrap anything in my codebase. Similar for implicitly unwrapped optionals.

      However, this is tricky when working with interface builder outlets. A common pattern that I observed can be seen in the following function:

      func updateLabel() {
        guard let label = valueLabel else {
          fatalError("valueLabel not connected in IB")
        label.text = state.title

      The alternative solution, obviously, would be to just to force unwrap the label, as that leads to a crash just like fatalError. Then, I'd have to insert ! though, also it wouldn't give me a nice succinct description of what actually is wrong. The better alternative here is to use expect as implemented above:

      func updateLabel() {
        valueLabel.expect("valueLabel not connected in IB").text = state.title

      4 Example

      So now that we've seen a couple of (hopefully) useful Optional extensions, I'll set up an example to better see how some of these extensions can be combined to simplify optional handling. First, we need a bit of context. Forgive me for the rather unconventional and impossible example:

      You're working in the 80s at a shareware distributor. A lot of student programmers are working for you and writing new shareware apps and games every month. You need to keep track of how many were sold. For that, you recieve an XML file from accounting and you need to parse it and insert it into the database (isn't it awesome how in this version of the 80s there's Swift to love but also XML to hate?). Your software system has an XML parser and a database (both written in 6502 ASM of course) that implement the following protocols:

      protocol XMLImportNode {
          func firstChild(with tag: String) -> XMLImportNode?
          func children(with tag: String) -> [XMLImportNode]
          func attribute(with name: String) -> String?
      typealias DatabaseUser = String
      typealias DatabaseSoftware = String
      protocol Database {
          func user(for id: String) throws -> DatabaseUser
          func software(for id: String) throws -> DatabaseSoftware
          func insertSoftware(user: DatabaseUser, name: String, id: String, type: String, amount: Int) throws
          func updateSoftware(software: DatabaseSoftware, amount: Int) throws

      A typical file looks like this (behold the almighty XML):

       <user name="" id="158">
         <package type="game" name="Maniac Mansion" id="4332" amount="30" />
         <package type="game" name="Doom" id="1337" amount="50" />
         <package type="game" name="Warcraft 2" id="1000" amount="10" />

      Our original Swift code to parse the XML looks like this:

      enum ParseError: Error {
          case msg(String)
      func parseGamesFromXML(from root: XMLImportNode, into database: Database) throws {
          guard let users = root.firstChild(with: "users")?.children(with: "user") else {
      	throw ParseError.msg("No Users")
          for user in users {
      	guard let software = user.firstChild(with: "software")?
      		.children(with: "package"),
      	    let userId = user.attribute(with: "id"),
      	    let dbUser = try? database.user(for: userId)
      	    else { throw ParseError.msg("Invalid User") }
      	for package in software {
      	    guard let type = package.attribute(with: "type"),
      	    type == "game",
      	    let name = package.attribute(with: "name"),
      	    let softwareId = package.attribute(with: "id"),
      	    let amountString = package.attribute(with: "amount")
      	    else { throw ParseError.msg("Invalid Package") }
      	    if let existing = try? softwareId) {
      		try database.updateSoftware(software: existing, 
      					      amount: Int(amountString) ?? 0)
      	    } else {
      		try database.insertSoftware(user: dbUser, name: name, 
      					      id: softwareId, 
      					    type: type, 
      					  amount: Int(amountString) ?? 0)

      Lets apply what we learned above:

      func parseGamesFromXML(from root: XMLImportNode, into database: Database) throws {
          for user in try root.firstChild(with: "users")
      		    .or(throw: ParseError.msg("No Users")).children(with: "user") {
      	let dbUser = try user.attribute(with: "id")
      		    .and(then: { try? database.user(for: $0) })
      		    .or(throw: ParseError.msg("Invalid User"))
      	for package in (user.firstChild(with: "software")?
      		    .children(with: "package")).or([]) {
      	    guard (package.attribute(with: "type")).filter({ $0 == "game" }).isSome
      		else { continue }
      	    try package.attribute(with: "name")
      		.zip3(with: package.attribute(with: "id"), 
      		   another: package.attribute(with: "amount"))
      		.map({ (tuple) -> Void in
      		    switch try? tuple.1) {
      		    case let e?: try database.updateSoftware(software: e, 
      							       amount: Int(tuple.2).or(0))
      		    default: try database.insertSoftware(user: dbUser, name: tuple.0, 
      							   id: tuple.1, type: "game", 
      						       amount: Int(tuple.2).or(0))
      		}, or: { throw ParseError.msg("Invalid Package") })

      If we look at this, then there're two things that immediately come to mind:

      1. Less Code
      2. More Complicated Looking Code

      I deliberately went into overdrive when utilizing the various Optional extensions. Some of them fit better while others seem to be a bit misplaced. However, the key is not to solely rely on these extensions (like I did above) when using optionals but instead to mix and match where it makes most sense. Compare the two implementations and consider which from the second example you'd rather implement with Swift's native features and which feel better when using the Optional extensions.

      That's all for today, thanks for reading!

      If you read this far, you should follow me (@terhechte)
      on Twitter

        Sun, 10 Dec 2017 #

        Patterns for Working With Associated Types

        1 Useful Patterns for Working Your Way Around Associated Types

        This blog post is based on a talk I gave at AppBuilders 2016 explaining protocols with associated types offering tips for using them.

        Swift is a powerful language with a very powerful type system. Among the features that define said type system are associated types. They can be defined on a protocol to allow implementors of the protocol to specialize certain types in a generic way:

        protocol Example {
          associatedtype Value
          var value: Value { get }

        In the snippet above, any type that implements the Example protocol has to define the Value type. Protocols with associated types can be understood as unfinished types. Compared to regular protocols, which can be used within Swift like normal types, those protocols can only be used as a generic constraint. This means that once your type requires an associated type, using it suddenly becomes much more complicated.

        The example below shows an example of finishing a type. By explicitly telling the compiler that the Value type is Int it is now able to understand ImplementExample fully.

        struct ImplementExample: Example {
          typealias Value = Int

        Associated types are useful for a certain kind of problems where subclassing and composition does allow you to build the right kind of abstractions. However, this is a seperate topic. The topic of this article, on the other hand, is what to do when you end up with associated types trouble.

        2 Associated Types Trouble

        The classic example of associated types trouble certainly is the following Swift error message:

        protocol 'Bookmarkable' can only be used as a generic constraint because it has Self 
        or associated type requirements
        var bookmarks: [Bookmarkable]

        This happens once your type conforms to a protocol which conforms to Equatable:

        protocol Bookmarkable: Equatable {
        struct User {
            var bookmarks: [Bookmarkable]

        Here, the problem is that Equatable contains a method == which has two paramters of type Self. Protocol Methods with Self parameters automatically opt in to associated types.

        In this article, we will be investigating several patterns that allow you to work your way around the associated type requirement or that show how such a type can be handled.

        3 Working Around Associated Types

        4 Make Your Types Equatable

        The first solution for the archetypical problem is also a really simple one. Instead of enforcing Equatable on your custom protocol, you can simply require your full fledged, final, types to conform to the Equatable protocol instead of your custom protocol. Consider the previously defined Bookmarkable protocol:

        protocol Bookmarkable {
        struct Bookmark: Bookmarkable, Equatable {
          var identifier: Int
        func ==(lhs: Bookmark, rhs: Bookmark) -> Bool {
          return lhs.identifier == rhs.identifier
        var myBookmarks: [Bookmark] = []

        In the example above, the Equatable requirement actually stems from the Bookmark type conforming to the Equatable protocol, not the Bookmarkable protocol itself. The actual Equatable information, however, lies in the new identifier property, which has been added to the Bookmark struct. As you can easily see, this also requires you to make the myBookmarks array require only elements of type Bookmark. A serious disgression if you're used to using protocols like partially anonymous types. A better solution, if your design allows for it, goes one step further by enforcing the new property which we introduced in this example.

        4.1 Equatable Properties

        Here, the idea is that we take one of the types that already implement Equatable in a proper way (i.e. Int, String, …) and add a new property requirement to our Bookmarkable protocol. Then, we can use this property to add Equatable support without actually implementing Equatable:

        protocol Bookmarkable {
            var identifier: Int { get }
        struct Bookmark: Bookmarkable {
            var identifier: Int
        var myBookmarks: [Bookmarkable] = []

        The main change, compared to the code above, is that the var identifier moved to the Bookmarkable protocol and that we removed the func ==.

        While this works better, it still has a major deficit. Since Bookmarkable does not directly comply with Equatable, you will not gain the standard library's methods that specifically deal with Equatable types. So instead of being able to call Array.contains like this:

        let ourBookmark = Bookmark(identifier: 0)
        let result = myBookmarks.contains(ourBookmark)

        You will have to use the more verbose closure-based version:

        let ourBookmark = Bookmark(identifier: 0)
        let result = myBookmarks.contains { (bookmark) -> Bool in
            return bookmark.identifier == ourBookmark.identifier

        5 Associated Types and Self

        Another vector which can introduce associated types into your codebase is the usage of Self:

        protocol Example {
          /// Indirect Associated Type
          var builder: Self { get }
          /// Indirect Associated Type
          func makeSomething(with example: Self)
        var myExamples: [Example] = []

        As you can see in the example above, using Self as a method parameter or using Self as a property type automatically introduces an associated type (like we saw with Equatable, earlier).

        The most helpful note here is that once you use a method instead of a property in order to return something of type Self you will not opt in to an associated type:

        protocol Example {
          /// No Indirect Associated Type
          func builder() -> Self
        var myExamples: [Example] = []

        This example works fine. No indirect associated type is introduced.

        6 Method-Only Types

        If your associated type requirement doesn't come from Equatable conformance but instead from your own use, you can double-check if you actually need these associated types.

        Take this example of a validator type:

        protocol Validator {
            associatedtype I
            func validate(_ input: I) -> Bool

        As the associated type is only used in one method, you can alternatively just make it a generic method and thus save yourself from introducing unnecessary unfinished types:

        protocol Validator {
            func validate<I>(_ input: I) -> Bool

        7 Hiding Behind Protocols

        This is an especially useful and flexible pattern. It can be used in many situations where you want to use protocols with associated types like a normal, full fledged type, but still be able to opt in to the generic part if necessary. The idea here is that you define two protocols that share common methods. Only one of those protocols contains associated types, the other does not. Your types conform to both protocols. This means that you can use the normal protocol as a type for all situations. If you, then, need to use the parts of the type that only affect the associated type, you can do so by means of a runtime cast.

        Begin by defining an associated Protocol ExampleAssociatedProtocol that is shadowed by a normal Protocol ExampleProtocol.

        /// The `Normal` Protocol
        protocol ExampleProtocol {
          var anyValue: Any { get }
        /// The Protocol with an associated type
        protocol ExampleAssociatedProtocol: ExampleProtocol {
          associatedtype Value
          /// Retrieving the actual associated type
          var value: Value { get }
        /// Conform to the `ExampleProtocol`
        extension ExampleAssociatedProtocol {
          var anyValue: Any {
            return value

        Now, you can use the ExampleProtocol as a normal type throughout your app in all situations where a protocol with an associated type would otherwise fail:

        struct World {
          var examples: [ExampleProtocol]
          let example: ExampleProtocol
          func generate() -> ExampleProtocol { 
            return example

        However, if you need to access the property that is specific to the ExampleAssociatedProtocol (value) then you can do so through at runtime.

        /// Custom type implementing `ExampleAssociatedProtocol`
        struct IntExample: ExampleAssociatedProtocol {
          var value: Int
        /// Custom type implementing `ExampleAssociatedProtocol`
        struct StringExample: ExampleAssociatedProtocol {
          var value: String
        /// Shadowing via `ExampleProtocol`
        let myExamples: [ExampleProtocol] = 
            [StringExample(value: "A"), IntExample(value: 10)]
        /// Runtime Casting
        for aNormalExample in myExamples {
          if let anAssociatedExample = aNormalExample as? IntExample {
          if let anAssociatedExample = aNormalExample as? StringExample {

        This will print "A10" as both types (IntExample and StringExample) are being identified at runtime via a cast from ExampleProtocol.

        8 Type Erasure

        8.1 The Problem

        Quite often, when Swift's associated types are dicussed, type erasure is mentioned as another solution to the problem of handling the issues that associated types bring along.

        Type Erasure in the context of associated types solves one particular problem. We'll use computers as an example. Back in the golden age of desktop operating systems, you could buy a desktop computer with many non-X86 CPU architectures: PowerPC, Alpha, Sparc, 68000, and so on. One of the many differences were the endianness of the architecture. Lets model these computers in Swift:

        protocol CPU {
            var littleEndian: Bool { get }
        struct PowerPC: CPU {
            let littleEndian = false
        struct X86: CPU {
            let littleEndian = true

        Next up, we want to define a protocol for a computer. It could be a desktop computer or a phone or maybe a game console, so we use a protocol. In order to model the CPU, we're using an associated type, so that the actual type can define the CPU:

        protocol Computer {
            associatedtype ProcessorType: CPU
            var processor: ProcessorType { get }
            var processorCount: Int { get }

        Based on this, we can now define a couple of systems:

        struct PowerMacG5: Computer {
            let processor = PowerPC()
            let processorCount = 2
        struct Xbox360: Computer {
            let processor = PowerPC()
            let processorCount = 1
        struct MacPro: Computer {
            let processor = X86()
            let processorCount = 1

        Now that we have all this, we'd like to perform a computation on all PowerPC based computers. I.e. something like:

        let powerComputers = [PowerMacG5(), Xbox360()]

        However, what would be the type of this? We can't use the Computer protocol, as it contains associated types. However, the associated types for the PowerMacG5 and the Xbox360 are the same, so in terms of types, Swift ought to understand that those things are kinda similar. However, there's no way to (easily) express this in the type system; both PowerMacG5 and Xbox360 are not the correct types for the array:

        // None of those work
        let powerComputers: [PowerMacG5] = [PowerMacG5(), Xbox360]
        let powerComputers: [Xbox360] = [PowerMacG5(), Xbox360]
        let powerComputers: [Computer] = [PowerMacG5(), Xbox360]

        Type erasure is a solution for this. The idea is to box the actual type into a generic wrapper so that Swift can coalesce around wrapper + type. The solution we're aiming for would look like this in the end:

        let powerComputers: [AnyComputer<PowerPC>] = [AnyComputer(PowerMacG5()), AnyComputer(Xbox360())]

        Now we would have our shared type, in this case it is AnyComputer<CPU>. Where does this mystic AnyComputer come from? We have to build it ourselves. This is a multi-step process, and requires quite a bit of boilerplate. We will start simple and expand step by step. This solution requires multiple types.

        8.2 An Abstract Class

        In essense, what we're going to build, is a generic wrapper (or box) that hosts a type conforming to a protocol with an associated type. It does so by implementing the requirements of the protocol and forwarding all invocations to the boxed type.

        The first new type we need for that is a base class that acts as a abstract class:

        class AnyComputerBase<Processor: CPU>: Computer {
            var processor: Processor {
            var processorCount: Int {

        This class should never be initialized, as it only provides an abstract template of what subclasses should implement. While other languages (like Java) allow explicitly marking classes as abstract, Swift doesn't offer us a way to do so. One solution to this is adding a fileprivate init to this class. However as that requires subclasses to be in the same file as this superclass, we can also just make the whole class private with an even better result. Now, other parts of the code won't even know about the existence of AnyComputerBase or even initialize it:

        private class AnyComputerBase<Processor: CPU>: Computer {

        Why do we even need this, and what does it do? As you can see, it just implements the Computer protocol by implementing the requirements and doing nothing in there. The more important part is that it moves the associated type from the protocol into a generic type for the class: AnyComputerBase<Processor: CPU>.

        Swift automatically figures out that Processor is the typealias for Computer.ProcessorType. However, when in doubt you can also add an extra typealias:

        class AnyComputerBase<Processor: CPU>: Computer {
          typealias ProcessorType = Processor

        8.3 A Box Type

        The next step is the most difficult to understand part of type erasure, which means that after this, it'll be easy. We will introduce another private type. This will be the actual box that houses our original type (the XBox360 or the PowerMac G5). Let's start by having a look at the code:

        private class AnyComputerBox<ConcreteComputer: Computer>: 
            private let internalComputer: ConcreteComputer
            override var processor: ConcreteComputer.ProcessorType {
        	return internalComputer.processor
            override var processorCount: Int {
        	return internalComputer.processorCount
            init(_ computer: ConcreteComputer) {
        	internalComputer = computer

        The most important concept here can be found in the very first line:

        private class AnyComputerBox<ConcreteComputer: Computer>: 

        Here, we define a new type AnyComputerBox which is generic over any computer (ConcreteComputer). This new type, then, is a subclass of our earlier abstract class AnyComputerBase. Remember that AnyComputerBase made the original ProcessorType of the Computer protocol generic by adding it as a generic parameter CPU. Now, our new box has a different generic type (Computer) and provides only its associated type ProcessorType to the abstract superclass. In a simpler explanation, this is what happens (in a mock language):

        1. Computer<CPU>
        2. AnyComputerBase<Processor: CPU>: Computer<CPU> where Computer.CPU = Processor
        3. AnyComputerBox<ConcreteComputer: Computer>: AnyComputerBase<ConcreteComputer.ProcessorType>

        So the box (AnyComputerBox) subclasses the abstract class and forwards in the Processor type via its own generic Computer type which also has a ProcessorType.

        Why do we do this? It makes the box generic over any computer so that any computer can be boxed into it.

        The rest of the class is simple. There's an internal computer internalComputer which is the actual type conforming to the Computer protocol. We're also overriding the two classes that are required by the protocol and forwarding the implementations of the internalComputer. Finally we have an initializer with a new ConcreteComputer (i.e. the Computer protocol).

        8.4 Putting it all together

        In the next and final step, we're building the actual type that will be used as the proverbial type eraser. Just as before, lets have a look at the code first:

        final class AnyComputer<Processor: CPU>: Computer {
            private let box: AnyComputerBase<Processor>
            var processor: Processor {
        	return box.processor
            var processorCount: Int {
        	return box.processorCount
            init<Concrete: Computer>(_ computer: Concrete) 
        	where Concrete.ProcessorType == Processor {
              box = AnyComputerBox(computer)

        This AnyComputer conforms to the Computer protocol and is generic over the CPU type that the protocol requires. Once again, we implement the protocol requirements (processor, and processorCount) and forward to a boxed type. This time we're forwarding to private let box: AnyComputerBase<Processor>. This box is set in the initializer where most of the magic happens:

        init<Concrete: Computer>(_ computer: Concrete) 
            where Concrete.ProcessorType == Processor {
          box = AnyComputerBox(computer)

        The problem with protocols with associated types is that you can't use them as property types. Here, init requires any type conforming to the Computer protocol. This is done by having a method-generic type Concrete that requires Computer conformance. Even more, we also add a constraint that makes sure that the generic Processor type of the new AnyComputer class is the same type as the associated type of the Concrete Computer type.

        And now comes the kicker: Since we cannot set a property as being of type Computer we, instead, have a property that is of AnyComputerBase with a generic type for the Processor. As our AnyComputerBox type is a subclass of AnyComputerBase we can literally put any box (that is a subclass of AnyComputerBase into this property. In this case, we're creating a new box with the Concrete Computer.

        Then we return the implementations of the contents of the box (i.e. the actual Concrete Computer) in our Computer implementations:

        var processorCount: Int {
            return box.processorCount

        8.5 Using It

        With all this machinery in place, we can finally use this in order to have different types (which share an associated type) in one container:

        let powerComputers: [AnyComputer<PowerPC>] = 
            [AnyComputer(PowerMacG5()), AnyComputer(Xbox360())]

        9 Conclusion

        Associated types are a powerful concept however they come with a fair share of difficulties. Most notably, as soon as you introduce an associated type you can't use it like you'd use normal full types. This article provided several patterns that make it a bit easier to handle associated type problems in your codebase. Each of these patterns has downsides though. In general, if you intend to use associated types in a protocol, one of the best solutions is to try to only use the types that implement this protocol instead of the protocol itself. Because then you don't even need those patterns.

        If you read this far, you should follow me (@terhechte)
        on Twitter

          Sun, 8 Oct 2017 #

          Taming SourceKitService for Less Xcode Memory Consumption

          1 Update [10/15/2017]

          <a href="">It seems that Xcode 9.1 beta 2 fixes this issue.</a>

          In my preliminary testing, everything worked fine. This feels really good.

          2 Original Article

          There were recently two popular Swift posts on Hacker News1 , 2, and one issue I saw coming up multiple times was the memory consumption of the tooling nee Xcode. One particular problem is that for some codebases the Swift sourcecode process SourceKitService consumes a huge amount of memory. I've had it rise to 30GB and beyond - at which point my system usually stalls and I'm not able to continue working for a couple of minutes.

          Oftentimes memory issues like these can be solved by reviewing your sourcecode with the same tools you also use to reduce your compile times. See:

          However, for some, complex, codebases this may not be enough. I've employed an awful little hack in order to at least keep my machine from stalling. I wrote a small little bash script that check the memory consumption of the SourceKitService every n seconds and if it goes beyond x megabytes of memory (by default 5.000) I restart it. I feel that this may be useful to some others so I'm sharing it here for posterity. Note that this is an awful hack and future versions of SourceKitService will probably (hopefully!) not need this anymore. Meanwhile, this might be of help to others:

          # Amount of seconds to wait between measures
          # Limit memory consumption to this many megabytes before killing the process
          while true; do 
            fields=`ps aux -m | grep -v grep | grep -i $name | tr -s ' '`
            mem=`echo $fields | cut -d ' ' -s -f 6| awk '{$1=$1/1024; print $1;}' | cut -d '.' -f 1`
            pid=`echo $fields | cut -d ' ' -s -f 2`
            if [ -z "$mem" ]; then
                echo "$name not running"
                sleep 15
            if [ "$mem" -gt $x ]; then
                echo "Killing $name pid $pid with mem $mem"
                kill -9 $pid
                sleep 5
            sleep $n

          To use this just paste that code into a file (say and do:

          chmod +x ./

          If you want to kill it, just hit CTRL=C.


          Why many developers still prefer Objective-C
          Dictionary and Set Improvements in Swift 4.0

          If you read this far, you should follow me (@terhechte)
          on Twitter