There’s a lot to love about Swift, which I’ve written about before. Today, however, I want to write about where the language falls short. This is a complicated issue with lots of nuance, so I’ll go into a couple of examples of where I think the language gets it right, where it gets it wrong, and what the future holds.

Defining within the language vs without

Take a look at Ruby.

Ruby’s attr_accessor is a way to define a setter and a getter for an instance variable. You use it like so:

class Person
	attr_accessor :first_name, :last_name
end

At first blush, this looks like a language feature, like Swift’s let and var property declarations. But Ruby’s functions can be called without parentheses, and this is just a function defined in the class scope (which we’d call a static function in Swift):

def self.attr_accessor(*names)
  names.each do |name|
    define_method(name) {instance_variable_get("@#{name}")} # This is the getter
    define_method("#{name}=") {|arg| instance_variable_set("@#{name}", arg)} # This is the setter
  end
end

If you can’t read Ruby, that’s okay. It uses a function called define_method to create a getter and setter for the keys that you pass in. In Ruby, @first_name means the instance variable named first_name.

This is one of the reasons I love Ruby’s language design — they first create the meta-tools to create useful language features, and then they use those tools to implement the language features that they want. Yehuda Katz explores how Ruby applies this idea to its blocks. Because Ruby’s language features are written with the same tools and in the same language that users have access to, users can also write features similar in style and scope to the ones that define the language.

Optionals

This brings us to Swift. One of Swift’s core features is its Optional type. This allows users to define whether a certain variable can be null or not. It’s defined within the system with an enum:

enum Optional<WrappedType> {
	case Some(WrappedType)
	case None
}

Like attr_accessor, this feature uses a Swift language construct to define itself. This is good, because it means users can create similar things with different semantic meanings, such as this fictional RemoteLoading type:

enum RemoteLoading<WrappedType> {
	case Loaded(WrappedType)
	case Pending
}

It has the exact same shape as Optional but carries different meanings. (Arkadiusz Holko takes this enum a step further in a great blog post.)

However, the Swift compiler knows about the Optional type in a way it doesn’t know about RemoteLoading, and it lets you do special things. Take a look at these identical declarations:

let name: Optional<String> = .None
let name: Optional<String> = nil
let name: String? = nil
var name: String?

Let’s unpack them. The first one is the full expression (with type inference). You could declare your own RemoteLoading property with the same syntax. The second uses the NilLiteralConvertible protocol to define what happens when you set that value to the literal nil. While this piece of syntax is accessible for your own types, it doesn’t seem quite right to use it with RemoteLoading. This is the first of a few language features that are designed to make Swift feel more comfortable to writers of C family languages, which we’ll come back to in a moment.

The third and fourth declarations are where the compiler starts using its knowledge of the Optional type to allow us to write special code that we couldn’t write with other types. The third one uses a shorthand for Optional<T> where it can be written as T?. This is called syntactic sugar, where the language lets you write common bits of code in simpler ways. The final line is another piece of syntactic sugar: if you declare an optional type, but don’t give it a value, the compiler will infer that its value should be .None/nil (but only if it’s a var reference).

You can’t access these last two optimizations with your own types. The language’s Optional type, which started out awesomely, by being defined within the existing constructs of language, ends up with special-cased compiler exceptions that only this type can access.

Families

Swift is defined to “feel at home in the C family of languages”. This means having for loops and if statements.

Swift’s for..in construct is special. Anything that conforms to SequenceType can be iterated over in a for..in loop. That means I can define my own types, declare that they’re sequential, and use them in for..in loops.

Although if statements and while loops currently work this way in Swift 2.2 with BooleanType, this functionality has been removed in Swift 3. I can’t define my own boolean types to use within if statements like I can with for..in.

These are two fundamentally different approaches to a language feature, and they define a duality in Swift. The first creates a meta-tool that can be used to define a language feature; the other creates a explicit and concrete connection between the feature of the language and the types of that language.

You could argue that types conforming to SequenceType are more useful than types conforming to BooleanType. Swift 3 fully removes this feature, though, so you have to fully commit: you have to argue that BooleanType is so useless that it should be completely disallowed.

Being able to conform my own types SequenceType shows that the language trusts me to make my own useful abstractions (with no loss of safety or strictness!) on the same level as its own standard library.

Operations

Operators in Swift are also worth examining. Syntax exists within the language to define operators, and all the arithmetic operators are defined within that syntax. Users are then free to define their own operators, useful for if they create their own BigInt type and want to use standard arithmetic operators with it.

While the + operator is defined within the language, the ternary operator ?: isn’t. Command-clicking on the + operator jumps you to its definition. Command-clicking on either the ? or the : of the ternary operator yields nothing. If you want to use a sole question mark or colon as an operator for your code, you can’t. Note that I’m not saying that it would be a good idea to use a colon operator in your code; all I’m saying is that this operator has been special-cased, hard-coded into the compiler, to add familiarity to those weaned on C.

In each of these three cases, we’ve compared two things: the first, a useful language syntax which the standard library uses to implement features; and the second, a special-case which privileges standard library code over consumer code.

The best kinds of syntax and syntactic sugar can be tapped into by the writers of the language, with their own types and their own systems. Swift sometimes handles this with protocols like NilLiteralConvertible, SequenceType, and the soon-defunct BooleanType. The way that var name: String? can infer its own default (.None) crucially isn’t like this, and therefore is a less powerful form of syntactic sugar.

I think it’s also worth noting that even though I love Ruby’s syntax, two places where it doesn’t have very much flexibility are operators and falsiness. You can define your own implementations for the Ruby’s existing operators, but you can’t add new ones, and the precedences are fixed. Swift is more flexible in this regard. And, of course, it was more flexible with respect to defining falsiness as well, until Swift 3.

Errors

In the same way that Swift’s Optional type is a shade of C’s nullability, Swift’s error handling resembles a shade of C’s exception handling. Swift’s error handling introduces several new keywords: do, try, throw, throws, rethrows, and catch.

Functions and methods marked with throws can return a value or throw an ErrorType. Thrown errors are land in catch blocks. Under the hood, you can imagine Swift rewriting the return type for the function

func doThing(with: Property) throws -> Value

as

func doThing(withProperty) -> _Result<Value, ErrorType>

with some internal _Result type (like antitypical/Result) that represents potential success or failure. (The reality is this _Result type isn’t explicitly defined, but rather implicitly handled in the bowels of the compiler. It doesn’t make much of a difference for our example.) At the call site, this is unpacked into its successful value, which is passed through the try statement, and the error, which jumps execution to the catch block.

Compare this to the previous examples, where useful features are defined within the language, and then syntax (in the case of operators or SequenceType) and syntactic sugar (in the case of Optional) are added on top of them to make the code look the way we expect it. In contrast, the Swift’s error handling doesn’t expose its internal _Result model, so users can’t use it or build on it.

Some cases for error handling works great with Swift’s model, like Brad Larson’s code for moving a robot arm or my JSON parsing code. Other code might work better with a Result type and flatMap.

Still other code might rely on asynchronicity and want to pass a Result type to a completion block. Apple’s solution only works in certain cases, and giving users of the language more flexibility in the error model would help cover this distance. Result is great, because it’s flexible enough to build multiple things on top of it. The try/catch syntax is weak, because it’s very rigid and can only be used in one way.

The Future

Swift 4 promises language features for asynchronous work soon. It’s not clear how these features will be implemented yet, but Chris Lattner has written about the road to the Swift 4:

First class concurrency: Actors, async/await, atomicity, memory model, and related topics.

Async/await is my leading theory for what asynchronicity in Swift will look like. For the uninitiated, async/await involves declaring when functions are async, and using the await keyword to wait for them to finish. Take this simple example from C#:

async Task<int> GetIntAsync()
{
    return new Task<int>(() =>
    {
        Thread.Sleep(10000);
        return 1
    });
}

async Task MyMethodAsync()
{
    int result = await GetIntAsync();
    Console.WriteLine(result);
}

The first function, GetIntAsync returns a tasks that waits for some amount of time, and then returns a value. Because it returns a Task, it is marked as async. The second function, MyMethodAsync, calls the first, using the keyword await. This signals to the system that it can do other work until the Task from GetIntAsync completes. Once it completes, control is restored to the function, and it can write to the console.

Judging from this example, Task objects in C# seem a lot like promises. Also, any function that uses the await keyword must itself be declared as async. The compiler can enforce this guarantee. This solution mirrors Swift’s error model: functions that throw must be caught, and if they don’t, they must be marked with throws as well.

It also has the same flaws as the error model. Rather than being mere syntactic sugar over a more useful tool, a brand new construct and a bunch of keywords are added. This construct is partially dependent on types within defined in the standard library and partially dependent on syntax baked into the compiler.

Properties

Property behaviors are another big feature that might come in Swift 4. There is a rejected proposal for property behaviors, which is set to be examined more closely for Swift 4.

Property behaviors let you attach a behavior like lazy to a property. The lazy property, for example, would only set up a value the first time it’s accessed. While you currently can use this particular behavior, it’s hard-coded into the Swift compiler. Property behaviors as proposed would allow the facility for the standard library to implement some behaviors and for users to define others entirely.

Perhaps this is the best of all worlds. Start with a feature that’s hard-coded in the compiler, and after the feature has gained some prominence, create a more generic framework which lets you define that feature through the language itself. At that point, any writer of Swift can create similar functionality, tweaked precisely to suit their own requirements.

If Swift’s error model followed that same path, Swift’s standard library might expose a Result type, and any function returning a Result would be able to use the do/try/catch syntax when it is most useful (like for many parallel, synchronous actions that can each fail). For error needs that don’t fit in to the currently available syntax, like async errors, users would have a common Result type that they can use. If the Result requires lots of chaining, users can flatMap.

Async/await could work the same way. Define a Promise or Task protocol, and things that conform to that would be await-able. then or flatMap would be available on that type, and depending on user’s needs, they could use the language feature at as high or as low of a level as needed.

Metaprogramming

I’d like to close with a note on metaprogramming. I’ve written extensively about metaprogramming in Objective-C, but it’s similar to what we’re working with here. The lines between code and metacode are blurry. The code in the Swift compiler is the meta code, and Swift itself is the code. If defining an implementation of an operator (as you do in Ruby) is just code, then defining a whole new operator seems like it has to be metacode.

As a protocol-oriented language, Swift is uniquely set up to let us tap into the syntax of the language, as we do with BooleanType and SequenceType. I’d love to see these capacities expanded.

The line where keywords stop and syntax starts, or where syntax stops and syntactic sugar starts, isn’t very well defined, but the engineers who write code in the language should have the ability to work with the same tools as those who develop the standard library.

Last week, I wrote about Promises, which are a high-level building blocks for dealing with asynchronous operations. Using just the fulfill(), reject(), and then(), functions, we can build up lots of functionality in a simple and composable way. I’d like to explore some of those here.

Promise.all

Probably the poster child for the value of promisifying all of your asynchronous callbacks is Promise.all. What this static function does is wait for all the promises you give it to fulfill, and once they have, Promises.all will fulfill itself with the array of all fulfilled values. For example, you might want to write code to hit an API endpoint once for each item in an array. map and Promise.all make that super easy:

let userPromises = users.map({ user in
	APIClient.followUser(user)
})
Promise.all(userPromises).then({
	//all the users are now followed!
}).onFailure({ error in
	//one of the API requests failed
})

To write Promise.all, we first need to create a new Promise the represents the state of all the promises combined. If the array is empty, we can fulfill immediately.

static func all<T>(promises: [Promise<T>]) -> Promise<[T]> {
    return Promise<[T]>(work: { fulfill, reject in
        guard !promises.isEmpty else { fulfill([]); return }
			
    })
}

Inside this promise, we need to loop through each promise and add a handler for success and one for failure. If any of the promises have failed, we can reject the larger promise.

for promise in promises {
    promise.then({ value in

    }).onFailure({ error in
        reject(error)
    })
}

Only when all of the promises are complete should it fulfill the larger promise. With a simple check to make sure none of the promises are rejected or pending and a little flatMap magic, we can fulfill the promise with the values of all the promises combined. The whole function together looks like this:

static func all<T>(promises: [Promise<T>]) -> Promise<[T]> {
    return Promise<[T]>(work: { fulfill, reject in
        guard !promises.isEmpty else { fulfill([]); return }
        for promise in promises {
            promise.then({ value in
                if !promises.contains({ $0.isRejected || $0.isPending }) {
                    fulfill(promises.flatMap({ $0.value }))
                }
            }).onFailure({ error in
                reject(error)
            })
        }
    })
}

Note that promises can only be fulfilled or rejected once. If fulfill or reject were called a second time, it wouldn’t have any effect on the state of the promise.

Because promises are state machines, they hold all the important state representing their completion. This is a different approach then NSOperation. While NSOperation holds one completion callback and the state of the operation, it doesn’t hold the resulting value, so you have to manage that yourself.

NSOperation also holds data about threading models and priority order, whereas promises don’t make any guarantees about how the work will be completed, just that it will be completed. This is borne out by looking at the Promise class itself. Its only instance variables are the state, which holds information about whether it’s pending, fulfilled, or rejected (and the corresponding data), and an array of callbacks. (It also holds an isolation queue, but that’s not really state.)

delay

One useful promise is one that resolves itself after some delay.

static func delay(delay: NSTimeInterval) -> Promise<()> {
    return Promise<()>(work: { fulfill, reject in
        let nanoseconds = Int64(delay*Double(NSEC_PER_SEC))
        let time = dispatch_time(DISPATCH_TIME_NOW, nanoseconds)
        dispatch_after(time, dispatch_get_main_queue(), {
            fulfill(())
        })
    })
}

Internally, this could be implemented with usleep or some other method of delaying, but dispatch_after is simple enough for our usage. This promise will become more useful as we build up other interesting promises.

timeout

Next, we’ll use delay to build timeout. This promise will be rejected after a delay.

static func timeout<T>(timeout: NSTimeInterval) -> Promise<T> {
    return Promise<T>(work: { fulfill, reject in
        delay(timeout).then({ _ in
            reject(NSError(domain: "com.khanlou.Promise", code: -1111, userInfo: [ NSLocalizedDescriptionKey: "Timed out" ]))
         })
    })
}

This isn’t that useful of a promise by itself, but it will be useful in building a few of the other behaviors that we want.

race

The partner to Promise.all, which fulfills when all promises are fulfilled, is Promise.race, which fulfills or rejects with the first promise that completes.

static func race<T>(promises: [Promise<T>]) -> Promise<T> {
    return Promise<T>(work: { fulfill, reject in
        guard !promises.isEmpty else { fatalError() }
        for promise in promises {
            promise.then({ value in
                fulfill(value)
            }).onFailure({ error in
                reject(error)
            })
        }
    })
}

Because promises can only be fulfilled or rejected once, calling fulfill or reject on the outer promise after it’s already been moved out of the .Pending state won’t have any effect.

With this function, timeout, and Promise.race, we can now create a new promise that either succeeds, fails, or times out within a certain limit. We’ll make it an extension on Promise.

extension Promise {
	func addTimeout(timeout: NSTimeInterval) -> Promise<Value> {
	    return Promise.race([self, Promise.timeout(timeout)])
	}
}

It can be used within a normal promise chain, like so:

APIClient
    .getUsers()
    .addTimeout(0.5)
    .then({
    	//we got our users within 0.5 seconds
    })
    .onFailure({ error in
    	//maybe our timeout error, maybe a network error
    })

One of the reasons I like promises so much is that their composability lets us build up behaviors easily. Promises usually require a guarantee that they will be fulfilled or rejected at some point, but our timeout function allows us to correct that behavior in a general fashion.

recover

recover is another useful function. It lets us catch an error and easily recover from it without messing up the rest of the promise chain.

We know the form we want our function to take: it should accept a function that takes our error and returns a new promise. Our method will also return a promise that we can use to continue chaining off of.

extension Promise {
	func recover<T>(recovery: (ErrorType) -> Promise<T>) -> Promise<T> {
		
	}
}

For the body of the method, we know that we need to return a new promise, and if the current promise (self) succeeds, we should forward that success to the new promise.

func recover<T>(recovery: (ErrorType) -> Promise<T>) -> Promise<T> {
	return Promise(work: { fulfill, reject in
		self.then({ value in
			fulfill(value)
		}).onFailure({ error in

		}
	}
}

onFailure, however, is a different story. If the promise fails, we should call the recovery function that was provided. That will give us a new promise. If that recovery promise succeeds, we can pass on that success to the new promise, and same if it fails.

//..
}).onFailure({ error in
	recovery(error).then({ value in
		fulfill(value)
	}).onFailure({ error in 
		reject(error)
	}
})
//...

The completed function looks like this:

extension Promise {
    func recover(recovery: (ErrorType) -> Promise<Value>) -> Promise<Value> {
        return Promise(work: { fulfill, reject in
            self.then({ value in
                fulfill(value)
            }).onFailure({ error in
                recovery(error).then({ value in
                    fulfill(value)
                }).onFailure({ error in
                    reject(error)
                })
            })
        })
    }
}

With this new function, we can recover from errors. For example. if the network doesn’t load the data we expect to see, we can load the data from a cache:

APIClient.getUsers()
    .recover({ error in 
        return cache.getUsers()
    }).then({ user in
    	//update UI
    }).onFailure({ error in
    	//handle error
    })

retry

Retrying is another capability we can add. To retry, we need a number of times to retry and a function that will generate the promise to be retried (so we can create the promise multiple times).

static func retry<T>(count count: Int, delay: NSTimeInterval, generate: () -> Promise<T>) -> Promise<T> {
    if count <= 0 {
        return generate()
    }
    return Promise<T>(work: { fulfill, reject in
        generate().then({ value in
            fulfill(value)
        }).recover({ error in
            return self.delay(delay).then({
                retry(count: count-1, delay: delay, generate: generate)
            })
        }).onFailure({ error in
            reject(error)
        })
    })
}
  • If the count is 1 or less, just generate the promise and return it.
  • Otherwise, create a new promise which generates the promise, and recovers it with a delay followed by a retry of count-1.

Creating retry builds on both delay and recover, which we wrote above.

In each of these examples, small, composable pieces come together to make simple and elegant solutions. All of these behaviors are built on the simple .then and .onFailure functions provided by the core of the promise implementation. Simply by formalizing what completion blocks look like, we can solve problems like timeouts, recovery, and retrying, and we can do so in a simple and reusable way. These examples still need some tests and verification, but I’ll be adding them slowly to the GitHub repo in the coming days and weeks.

Promises are a way to chain asynchronous tasks. Normally, asynchronous tasks take a callback (or sometimes two, one for success and one for failure), in the form of a block, that is called when the asynchronous operation is completed. To perform more than one asynchronous operation, you have to nest the second one inside the completion block of the first one:

APIClient.fetchCurrentUser(success: { currentUser in
	APIClient.fetchFollowers(user: currentUser, success: { followers in
		// you now have an array of followers
	}, failure: { error in
		// handle the error
	})
}, failure: { error in
	// handle the error
})

Promises are a way of formalizing these completion blocks to make chaining asynchronous processes much easier. If the system knows what success and what failure look like, composing those asynchronous operations becomes much easier. For example, it becomes trivial to write reusable code that can:

  • perform a chain of dependent asynchronous operations with one completion block at the end
  • perform many independent asynchronous operations simultaneously with one completion block
  • race many asynchronous operations and return the value of the first to complete
  • retry asynchronous operations
  • add a timeout to asynchronous operations

The code sample above, when converted into promises, looks like this:

APIClient.fetchCurrentUser().then({ currentUser in
	return APIClient.fetchFollowers(user: currentUser)
}).then({ followers in
	// you now have an array of followers
)}.onFailure({ error in
	// hooray, a single failure block!
})

(You’ll note that promises are a thing that turns nested/indented code into flat code: a promise is a monad.)

Promises grew to ascendence in the JavaScript community. Because Node.js was designed to have lots of asynchronous capabilities, even simple tasks would require chains of method calls with asynchronous callbacks. This grew unwieldy even after only 3 or 4 of these actions. Promises saved the day, and they’re now part of the official JavaScript ES6 spec. This blog post goes into great detail on how JavaScript’s promises work.

One of the great things about the JavaScript Promise implementation is that there is a very clearly defined spec, called A+, which can be found at promisejs.org. This meant that multiple promise implementations could sprout, and they were fully interoperable, due to JavaScript’s weak type system. As long as your Promise implementation has a then function that conforms to the spec, it can be chained with promises from other libraries. This is awesome.

While writing the Backchannel API (which was in Node), I grew to love Promises. The A+ spec has a really nice API, eschewing the functional names you would expect on a monad for the simpler, easier-to-understand then (which is overloaded to act as both flatMap and map) . While this API isn’t for everyone, (in particular, I can fully understand why you’d prefer the explicitness of the functional names), I really do like it, and I set out to implement a similar library in Swift.

You can find this library on Github. The process of writing it was enlightening, and I’d like to share some of the things I learned here.

Enums are awesome

Yeah, everyone knows. Enums are great. But because Promises are essentially a state machine, enums are a particularly excellent fit here. The reference implementation of JavaScript’s Promise starts out like this:

var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

function Promise() {
  // store state which can be PENDING, FULFILLED or REJECTED
  var state = PENDING;

  // store value or error once FULFILLED or REJECTED
  var value = null;

  // store sucess & failure handlers attached by calling .then or .done
  var handlers = [];
}

I couldn’t contrive a more perfect example for Swift’s enums if I tried. Here’s the same code in Swift:

enum State<Value> {
    case Pending
    case Fulfilled(value: Value)
    case Rejected(error: ErrorType)
}

final class Promise<Value> {    
    private var state: State<Value>
    private var callbacks: [Callback<Value>] = []
}

The additional data, because it is contingent on the specific state the promise is in, is stored as an associated value on each of the enum cases. Since it doesn’t make any sense for a promise to be in the .Pending state but have a value, the enum makes that completely inexpressible in the type system.

My only criticism is that generic types can’t be nested inside other types, and this is fixed in Swift 3.

Type systems are nice

When creating a new JavaScript promise, you can use a convenience initalizer:

var promise = new Promise(function(resolve, reject) {
	someAsyncRequest(function(error, result) {
		if (error) {
			reject(error);
		}
		resolve(result);
	});
});

You pass it a function that takes two functions: one for if the promise should succeed, and one for if it should fail. For these two functions, order matters. And because JavaScript isn’t type-safe, if you mis-order the functions in the first line above, writing reject, resolve (which I did more often than I’d like to admit), you can easily pass an error into the resolve function. Swift’s type-safety, on the other hand, means that the reject function has the type (ErrorType) -> Void) and won’t accept your successful result. Gone is the worry that I’ll mess up the order of the reject and resolve functions.

Too much types can be frustating

My Promise type is generic over Value, which is the type of the value that comes out of it. This means you can rely on type inference to write code with no types.

let promise = Promise(value: "initialValue") // a fulfilled Promise<String>

Because promises are often chained, relying on inference to figure out what your types will be is especially useful. Having to add explicit types to each step in the chain would be very frustrating, and ultimately not particularly Swift-like.

My first crack at this was generic over Error as well. This strictness meant that creating a fulfilled promise required you to specify your error’s type up-front, every time.

let promise = Promise<String, APIError>(value: "initialValue")

This adds a lot of unnecessary baggage to what used to be a simple line of code, so I remove the ability to specify what the type of the error was.

Unfortunately, removing explicit error types means that there’s one small type-system goodie that I have to miss out on. If you make an empty enum called NoError, it effectively expresses that the promise can’t fail. Since empty enums can’t be initialized, there’s no way to make the promise enter the rejected state. This is a sad loss, but ultimately, I decided it was worth it, since it made using promises in every other context way simpler. I hope using the class in practice will give me the insight into whether this was a good decision or not.

Relatedly, Swift’s generics manifesto includes “default generic arguments”, which would be a great way to get around this problem: you’d be able to say the default is ErrorType, and if anyone wants to get more specific, they have that capacity.

Functional methods are hard to grok

The promise type is a monad, meaning you can call flatMap on it. The function that you pass into flatMap returns a new promise, and that promise’s state becomes the state of the chain.

The name of the flatMap function is completely inscrutable, though. It doesn’t express what’s actually happening here, in an easy-to-read way. This is part of the reason I prefer A+’s Promise API. The then function in JavaScript overloaded to act as both flatMap (returning a new promise for the chain) and map (returning a new value for the next promise in the chain). then now just means “do this thing next” without respect to exactly how the next thing works.

Since Swift’s type system knows when functions return Void, then can also be overloaded to accept functions that don’t return anything, to allow you to “tap” into the chain. I’ll know more when I use this class in a project, but I look forward to seeing if this “tap” version of then is useful. A triple overload might be too much, but I think it’ll be nice to be able to use then without having to think about the precise functional term for what I’m trying to do.

Tests are good

Once I wrote a basic implementation of the class, I wrote a few tests. I got some experience with XCTest’s expectationWithDescription and waitForExpectationsWithTimeout, which are pretty nice APIs to work with.

Like the cookbook project, having a full suite of tests for the Promise class was extremely useful. As always, there was some up front cost in writing the tests, but it was totally worth it. While I was refactoring and cleaning up this code, the tests caught numerous errors. A promise implementation is very fickle, and tiny details about the order that code is executed change the behavior of the class in subtle ways. Having a test suite that confirms that a refactor is truly isomorphic is great.

Threading is hard

Because it inherently deals with threading and asynchronocity, Promise needs to be a thread-safe class. To make the class thread-safe, its instance variables need to be accessed all from the same queue. This was harder than I expected it to be. Even after I’d thought I’d done it right, there were still a few places where I’d screwed it up.

Two of the tests in particular were very flaky and would fail every 5-10 times I ran the test suite. There’s nothing scarier than a flaky test, because it’s so easy to just assume it was a cosmic ray that hit your computer’s RAM at the exact right moment to cause your test to fail.

One of the flaky tests was resulting in an EXC_BAD_ACCESS, which was very confusing, because I couldn’t think of a way in Swift that I would be accessing bad memory. It took me a while, but I got finally got a log message that suggested it was a threading issue. I was appending things to an array from multiple threads simulataneously. I corrected the code that accesses the instance variables to use the dispatch queue correctly, and the flaky tests became reliable.

You can find the code on Github. I haven’t made it a full library yet, with public declarations and a podspec yet. I want to see what it’s like to use it in a real app first.

Promises seem complex and magical, but the implementation flows almost naturally from the types that each version of then has. Once I had an implementation that worked, I could write tests against it, and those tests enabled me slowly refactor my code and find edge case bugs.

While Swift’s actual native Dictionary type has a pretty complex implementation (undoubtedly for performance reasons), Swift gives us the tools to write a beautiful and simple one with very little code. We’ll start small and add features as we go.

A quick recap of how dictionaries work: dictionaries allow you to set and retrieve a value using a key, which can be any type. They are usually backed by an array, although they can be backed by a tree as well. We will explore an array-backed dictionary in this post, mostly because I don’t know how tree-backed dictionaries work yet.

Since our dictionary will be backed with an array, we need a way to convert the key that’s given into an integer, and then a way to force that integer into the bounds of our array. These two methods are the hashing function and the modulus operation, respectively. By hashing, we can consistently turn our key (usually a string, but can be any type that is Hashable) into a number, and by taking the modulus with respect to the length of the array, we’ll get a consistent slot in the array to set and retrieve the value.

I took some inspiration from Mike Ash’s Let’s Build NSMutableDictionary, particularly the rules for resizing.

Let’s get started. We know that we want this to be generic over Key and Value, and that Key has to be Hashable. Something that is Hashable is also Equatable, which we will need as well, but we will get for free.

struct Dictionary<Key, Value where Key: Hashable> {
	private var storage = //some Array...
    
    subscript(key: Key) -> Value? {
        get {
	        return nil
        }
        set {
        }
    }
}

This is the basic structure of our type. We know our array has to be generic over …something, but we don’t know what yet. Because there may be collisions, which are two different Key objects that hash and mod to the same position in the array, each placeholder object will need to support storing multiple values. Let’s design Placeholder:

struct Placeholder<Key, Value where Key: Hashable> {
    var values: [(Key, Value)] = []
}

This object will hold many keys and values that have all hashed and modded to the same spot in the dictionary. If we’ve designed our dictionary well, there won’t be more than one key-value pair in each Placeholder often, but it will happen. A nice implementation of this Dictionary might use a linked list for the values property of the Placeholder. I’ll leave that as an exercise for the reader.

Now that we know roughly what Placeholder looks like, we know what the storage will look like.

private var storage = Array(count: 8, repeatedValue: Placeholder<Key, Value>())

We start with a randomly chosen size for the array. It helps to pick a power of two, because modding by a power of 2 is a little bit faster than any other number. Until we implement resizing, it won’t really matter what size we pick. With the Array(count:repeatedValue:) constructor, each spot in the array now has a placeholder that we can add values to.

To set values in the dictionary, we need to hash the key (and absolute value it, since the hash can sometimes come back as negative), and then mod it by the size of the array.

set {
    let position = abs(key.hashValue) % storage.count
    //...
}

To actually add this value to the dictionary, we need to a) make sure the new value is not nil, b) find the placeholder at position, and c) add the key and value to the placeholder.

set {
    guard let value = newValue else { return }
    let position = abs(key.hashValue) % storage.count
    storage[position].values.append((key, value))
}

For a basic implementation of the setter, that’s really all we need. (I’ve left out some small details, like what happens when you try to set the same key twice. We’ll tackle that soon.)

For fetching the value, process is pretty similar. Hash the key, absolute value, mod, and then we have the placeholder at that position. To retrieve the value from the placeholder, I’m going to delegate that to the placeholder itself.

get {
    let position = abs(key.hashValue) % storage.count
    return storage[position].firstValue(matchingKey: key)
}

That method is where the real magic will happen. We need to find the first key-value pair that has that key. A method on SequenceType called first(where:) will land in Swift 3, but until we have that bounty, we will need to use the longhand lazy.filter( /* block */ ).first

func firstValue(matchingKey key: Key) -> Value? {
    let matchingKeyValuePair = values.lazy.filter({ $0.0 == key }).first
    //...
}

Once we have the tuple that represents the pair, we can call .1 on it to extract the value.

func firstValue(matchingKey key: Key) -> Value? {
    return values.lazy.filter({ $0.0 == key }).first?.1
}

That’s pretty much it for a basic implementation of Dictionary. 23 lines of Swift. You can find all the code together as a gist here.

There are a few interesting things left to implement on our type. First, an extremely lazy implementation of generate() so that our Dictionary conforms to SequenceType:

extension Dictionary: SequenceType {
    typealias Generator = IndexingGenerator<[(Key, Value)]>
    func generate() -> Dictionary.Generator {
        return storage.flatMap({ $0.values }).generate()
    }
}

Next, a way to remove keys. First, from the placeholder:

extension Placeholder {
    mutating func removeValue(key key: Key) {
        values = values.filter({ $0.0 != key })
    }
}

and then on Dictionary itself:

extension Dictionary {
	mutating func remove(key key: Key) {
	    let position = abs(key.hashValue) % storage.count
	    storage[position].removeValue(key: key)
	}
}

We’ll add a call to remove(key:) before we set any new values. This will ensure the same key can’t point to two different values.

Lastly, let’s take a look at resizing. When a dictionary has too many objects in it, its backing storage should resize itself. Typically, “too many objects” is defined as having a load factor (number of objects divided by backing array length) above 2/3 or 3/4. I chose 0.7.

extension Dictionary {
	private let maxLoadFactor = 0.7
	
	private var size: Int {
		return storage.count
	}
	
	var count: Int {
		return storage.flatMap({ $0.values }).count
	}
	
	var currentLoadFactor: Double {
		return Double(count) / Double(size)
	}
}

(The implementation of count is extremely lazy, again. Ideally, the Dictionary would keep track of how many objects have been added to — and removed from — it, but that is tougher than it looks.)

mutating func resizeIfNeeded() {
    if currentLoadFactor > maxLoadFactor {
        //resize storage
    }
}

This is the part where Swift’s value semantics get really really weird. When Mike Ash built his NSMutableDictionary, he created a fixed-size dictionary, and wrapped it in a mutable size dictionary. When he needed to resize, he would generate a new fixed-size dictionary (with double the size), and copy all the items to it manually.

We don’t have to do this in Swift. In a Swift struct, assigning self to a variable makes a full copy of it.

let oldDictionary = self
//...

Once we have a copy of the dictionary, we can reset our storage variable to an array with double the size. (Doubling the size ensures that we remain a power of two.)

//...
storage = Array<Placeholder<Key, Value>>(count: size*2, repeatedValue: Placeholder<Key, Value>())
//...

Once that’s done, our dictionary is empty, and we have to copy all the values from the oldDictionary to the current one:

//...
for (key, value) in oldDictionary {
	self[key] = value
}

Here’s the complete resizeIfNeeded() function:

mutating func resizeIfNeeded() {
    if Double(count) / Double(size) > maxLoadFactor {
        let oldDictionary = self
        storage = Array<Placeholder<Key, Value>>(count: size*2, repeatedValue: Placeholder<Key, Value>())
        for (key, value) in oldDictionary {
            self[key] = value
        }
    }
}

self, inside a Swift struct, is a way of accessing the values and functions of the current type, but it’s also a very moldable and mutable thing. You can set it to new values, copy it to others, and generally treat it as if it were just another variable reference.

I joked two weeks ago that Swift is a more dynamic language than Objective-C, Ruby, or Python because you can change its falsiness behavior, but here we have another situation where you can mutate something in Swift that you couldn’t in Objective-C: the reference to self itself. We could have written self = Dictionary(size: size*2) in this method, and it would have been perfectly valid Swift. To developers who are used to writing object-oriented code where an object’s identity is paramount, this is fundamentally weird.

The full implementation, with sequencing, removing, and resizing can be found as a gist. Besides the lazy count/generate() implementations, I’m pleased with the way this little project turned out.

I’ve had a few beginner programmers ask me how to go from being able to write some code to being able to write nice code. I have a few book recommendations to this end. These books are great for people who are just starting out, but they also taught me a good bit when I was a few years into my programming career. A lot of them are in different languages — C, Ruby, Java — so reading them can be a bit of a challenge. For the most part, though, the concepts translate cleanly into whatever any language, and developing your polyglot skills early is never a bad thing.

Practical Object-Oriented Design in Ruby

by Sandi Metz

Longtime readers know about about my partiality to Sandi Metz. I think she does some of the best work out there explaining simple concepts to smart people. Practical Object-Oriented Design in Ruby, or POODR, is no exception.

Using a simple example of bike repair, she shows explains object-oriented theory in tiny examples, slowing building them up from an object with one method on it, to a full implementation of Fowler’s Replace Condtional with Polymorphism pattern from Refactoring (which I’ll talk about it in a moment). The concepts in this book are not mindblowing, but they’re patiently explained, start slow, and build on each other perfectly.

Design Patterns

by Gamma, Helm, Johnson, and Vlissides

Colloquially known as Gang of Four, this book was published in 1994. It’s one of the first books that just lays out a list of commonly used design patterns, explains when and where they should be used, and shows examples of how to use them. Several of the books I’ll recommend are like this. Even though they look like textbooks, they’re worth reading straight through like a normal book. When the time comes to use one of these patterns, you’ll know which book and chapter to flip to to get the details you need.

Gang of Four was written for a world of desktop GUI applications, and this is made clear by some of the patterns. For example, the Command pattern is clearly useful for undoable menu commands. These kinds of actions are rarer on iOS and the web, so the pattern has fallen out of favor. Nevertheless, seeing the path from problem to solution has helps you come up with creative solutions to your own problems.

Patterns of Enterprise Application Architecture

by Martin Fowler

If Gang of Four was written in an age of GUI desktop apps, Patterns of Enterprise Application Architecture was written in an age of web services. While its title suggests that it’s extremely dry, I’ve found it to be a very useful collection of patterns. It reads as practically a cookbook for a framework like Ruby on Rails, so much so that I wouldn’t be surprised if DHH read this book before setting out to write Rails.

The patterns, having been written for the web, deal with forms, HTML, and databases. While the former two categories are interesting, the database patterns can be used when writing modern iOS apps. If you want to think about how an ORM like Core Data (or ActiveRecord) is written, this book is the place to start. For example, Core Data uses the Identity Map, Lazy Load, Metadata Mapping, and Query Object patterns. Like Gang of Four, we don’t need to use all these patterns in our day-to-day, but seeing how its authors solved their problems is enlightening.

Refactoring

by Martin Fowler

This book is also by Martin Fowler. It gives a precise definition for refactoring:

I’ve been asked, “Is refactoring just cleaning up code?” In a way the answer is yes, but I think refactoring goes further because it provides a technique for cleaning up code in a more efficient and controlled manner.

And describes how refactoring fits into the process of normal development:

When you use refactoring to develop software, you divide your time between two distinct activities: adding function and refactoring. When you add function, you shouldn’t be changing existing code; you are just adding new capabilities.

After the introductions and defintions, Fowler dives into a list of refactorings. He starts from simple ones, like Extract Method, and onto more complex ones like Introduce Null Object. Like with the previous two books, it pays to read this one straight through.

Domain-Driven Design

by Eric Evans

While the other books are mostly lists of patterns, this book follows a slightly more narrative arc. A developer works with a domain expert in shipping goods overseas to build an application to manage boat itineraries. In the process, you learn about how to model a domain from the initial research phases to the actual coding. This book taught me about value types two years before Swift and its value types were announced.

The made-up Socratric dialogues between Evans’s programmer and domain expert are helpful too. Some people think that in an ideal world, a product manager can sit in-between the developers and the stakeholders. In the real world, you (as the developer) are ultimately responsibilty for clearly expressing the abilities and limitations of the software, and this book shows what those conversations can and should look like.

How to think vs what to think

Each of these five books is valuable in a special way — not just for teaching you their contents, but also for meta lesson of teaching you how to think about the problems you face. They all follow a general structure: given this problem, here’s a solution. Connecting the problems to the solutions helps you see the thought process that leads to that solution, and ultimately helps you apply that process to other problems.

In Python, zero and None, as well as empty lists, dictionaries, and strings, are falsy. If something is falsy, it means that it can be used in the condition of an if statement, and it’ll follow the else branch. For example, in Python:

if []:
	# will not be evaluated
else:
	# will be evaluated
	
if 0: 
	# will not be evaluated
else:
	# will be evaluated

In Swift, on the other hand, only true booleans can be used in an if statement. Using nil, an empty array, or really any other type in an if statement simply won’t compile:

if Array<String>() {
// error: type 'Array<String>' does not conform to protocol 'BooleanType'

Both Python and Swift are consistent, which is a great quality to have. In Swift, you know that nothing besides a boolean will work in an if statement. In Python, you know every collection type, integer, nil value (None), and boolean will work. Consistency seems easy, until you notice how bad other languages get it.

JavaScript, for example, is a real shitshow. false, null, and undefined are falsy, which is more or less fine. But 0 and "" are falsy as well, even though [] and {} are truthy. (And don’t even bother trying to describe JavaScript’s equality behavior.)

Objective-C, love it though I do, is also an example of an inconsistent language in this respect. nil, NO, false, and 0 are falsy, while @[], @{}, @0, and @NO are truthy. Ruby is mostly good, allowing only nil and false to be falsy. I prefer Swift’s absoluteness strictness to Ruby’s behavior.

Consistency is good, but even better is utility. Swift’s falsiness rules are good, but Python’s are useful.

I have two pieces of evidence for why Python’s rules are more useful than Swift’s (and pretty much every other language.)

The first piece of evidence is the present? methods in Rails’s ActiveSupport. I’ve written about present? here before, but, in brief, it’s a way to get around the fact that the only thing that isn’t mutable in the Ruby runtime is falsiness. Every object has a chance to describe if it’s #present?. nil is not present, as well as the empty array and string. You can override present? for your own objects as well, if you have custom collections or null objects. This lets you write code like:

if myObject.present? {
	
} else {

}

to override Ruby’s stubborn falsiness. ActiveSupport’s presence is just plain useful, which is why calls to .present? (and .blank?, its opposite) are littered all over Rails codebases.

The second piece of evidence I have is how awkward Swift is at dealing with optional values in conditionals. Pay attention to how much you’re checking if a thing is empty or nil (blank?, in Ruby parlance) in your code. It’s really frequent for me. For example, the text property on UITextField is optional. If you want to check if the text is present, you have to do this awkward dance:

if let text = textField.text where !text.isEmpty {
	// we have some text
} else {
	// the string is either empty or nil
}

If you think this code is not awkward, try reversing the conditional. I’ll wait. (Here’s a hint: you can’t just remove the not operator.)

Soon, you’re adding a method onto Optional specifically for strings:

protocol TextContaining {
    var isEmpty: Bool { get}
}

extension String: TextContaining { }

extension Optional where Wrapped: TextContaining {
    var isEmpty: Bool {
        switch self {
        case let .Some(value):
            return value.isEmpty
        case .None:
            return true
        }
    }
}

You don’t have to live like this! You deserve nice things! (Like Python’s falsiness.)

Swift, unlike all of the other languages I’ve mentioned here, is a highly dynamic language. It will allow you to add code to change the compiler’s falsiness behavior.

Here are the docs for BooleanType:

Types that conform to the BooleanType protocol can be used as the condition in control statements (if, while, C-style for) and other logical value contexts (e.g., case statement guards).

Yessssss.

Only three types provided by Swift, Bool, DarwinBoolean, and ObjCBool, conform to BooleanType. Expanding this set to include types that represent more than simple boolean values is discouraged.

Sorry, Chris Lattner, I’m going for it.

extension String: BooleanType {
    public var boolValue: Bool {
        return !self.isEmpty
    }
}

Done! Now, we can use strings in conditionals. This code compiles and works as expected:

if "" {
	// this code will not be executed
} else {
	// this code will be executed	
}

We can do the same for Dictionary and Array. For optional, we should check if the Wrapped type conforms to BooleanType:

extension Optional: BooleanType {
    public var boolValue: Bool {
        switch self {
        case .None:
            return false
        case .Some(let wrapped):
            if let booleanable = wrapped as? BooleanType {
                return booleanable.boolValue
            }
            return true
        }
    }
}

Now, if you have a Boolean wrapped in an Optional, it will do the thing you expect, instead of giving you a compiler error, and you no longer have to do the weird optionalBool ?? true workaround.

The big question is “Should I do this in production?”. The answer is…maybe? If it’s a library that goes into other people’s apps, definitely do not do this. If you do it in your app, it shouldn’t break any third party code: because it wouldn’t compile, they couldn’t use it anyway. And Swift is still strongly typed, so you can’t ever compile the code myArray == false.

I think it’s great that Swift is built on small composable pieces (like BooleanType) that the standard library uses to define itself within the language. (Types like ArrayLiteralConvertible follow a similar pattern.) It’s also surprising that none of the “dynamic” languages that we’re used to allow this kind of mutation of fundamental language structure. In the meantime, I have to decide if I want to try to use this anywhere.

In a language like JavaScript, configuration objects (or, as they’re known by JS convention, options), are just a dictionary. Default options are merged into the dictionary using a function like Underscore.js’s _.defaults.

Because of Swift’s type system, typeless dictionaries aren’t as nice to use as they are in a more dynamic language like JavaScript. Structs, on the other hand, make for great configuration objects. Unfortunately, configuring those configuration objects is sometimes a bit unweildy. Let’s take a look at the data for a form’s text field.

struct FieldData {
	let title: String
	let placeholder: String
	let keyboardType: UIKeyboardType
	let secureEntry: Bool
	let autocorrectType: UITextAutocorrectionType
	let autocapitalizationType: UITextAutocapitalizationType
}

This struct will give us an implicit “memberwise” initializer, but let’s write it explicitly.

init(title: String, placeholder: String, keyboardType: UIKeyboardType, secureEntry: Bool, autocorrectType: UITextAutocorrectionType, autocapitalizationType: UITextAutocapitalizationType) {
	self.title = title
	self.placeholder = placeholder
	self.keyboardType = keyboardType
	self.secureEntry = secureEntry
	self.autocorrectType = autocorrectType
	self.autocapitalizationType = autocapitalizationType
}

To use this particular initializer, you’ll have to pass in all the defaults yourself. To rectify that, we can make a different intializer that has defaults built in, by using the default parameter syntax. It’s getting really unwieldy, so let’s break it onto multiple lines as well.

init(title: String,
	placeholder: String = "",
	keyboardType: UIKeyboardType = .Default,
	secureEntry: Bool = false,
	autocorrectType: UITextAutocorrectionType = .None,
	autocapitalizationType: UITextAutocapitalizationType = .None)
	{
		self.title = title
		self.placeholder = placeholder
		self.keyboardType = keyboardType
		self.secureEntry = secureEntry
		self.autocorrectType = autocorrectType
		self.autocapitalizationType = autocapitalizationType
}

This initializer is mostly pretty good. Because of all of the default values, you can use this intializer with just a title, like so:

let fieldData = FieldData(title: "First Name")

You can also use it with any of the defaults overridden, like so:

let fieldData = FieldData(title: "First Name", secureEntry: true)

Even though secureEntry is the fourth parameter, any parameters with defaults can be skipped. Swift does the right thing here, and that’s awesome. We could leave this as-is, but I wanted to go a step further. I don’t like how big the initializer is. Each property of the struct is declared in 3 places: first, in the property declaration; second, in the initializer’s function declaration, and lastly in the setter in the body of the declaration. This might not seem like a big deal, but every time you add, remove, or change a property, you’ll have to touch three pieces of code.

I toyed around with a few ways to fix this issue, including making the instance variables optional and filling in the defaults at the usage site, but that ended up being just as clunky as the big initializer. What I settled on was: instead of making the variables optional, I made them mutable. That solves quite a few problems. Let’s take a look:

struct FieldData {
	let title: String
	var placeholder = ""
	var keyboardType = UIKeyboardType.Default
	var secureEntry = false
	var autocorrectType = UITextAutocorrectionType.No
	var autocapitalizationType = UITextAutocapitalizationType.None
	
	init(title: String) {
		self.title = title
	}
}

Our initializer is now dead simple. It has only the required parameters in it. Everything else has an easy to read default in the property declaration. We could add more spacing or documentation to those properties, as needed.

Next, I used a great little microlibrary called Then, which helps clean up initialization of objects. It’s a dependency, but it has a really simple definition:

public protocol Then {}

extension Then {
    public func then(@noescape block: inout Self -> Void) -> Self {
        var copy = self
        block(&copy)
        return copy
    }
}

That’s it. From this, we can extend our FieldData struct with Then:

extension FieldData: Then { }

And go to town:

let fieldData = FieldData(title: "Password").then({
	$0.secureEntry = true
})

While this solution does have mutable properties, I think the wins in the readability of the call site and changeability of the code are worth it.

Using then for view configuration

The then extension is a really useful library to have in your app. By default, it extends all NSObject types:

extension NSObject: Then { }

Since everything in Cocoa Touch inherits from NSObject, you can now use this function to configure lots of types, and you can do so at the declaration of the property. Swift will let you initialize things in-line (as long as they’re effectively a one line expression):

let footerContainer = UIView().then({
    $0.backgroundColor = UIColor.grayColor()
})

Since then returns self, you can also chain calls to then. By moving common view configuration into a free function, like so:

struct Style
	static func whiteButton(inout button: UIButton) {
		button.setTitleColor(UIColor.whiteColor(), forState: .Normal)
		button.contentVerticalAlignment = .Center
		
		button.setBackgroundColor(UIColor.whiteColor(), forState: .Normal)
		button.setBackgroundColor(UIColor.lightGrayColor, forState: .Hightlighted)
	}
}

Because this function has the same form as the function that then expects, you can pass it straight to then, and call then a second time to do more customized configuration:

let button = UIButton().then(Style.whiteButton).then({
	$0.setTitle("Continue", forState: .Normal)
})

Go grab the then function. It’s super useful.

Ruby allows developers to easily make new namespaces using the module keyword. For example, the ActiveRecord namespace contains a class called Base, like so:

module ActiveRecord
	class Base
	
	end
end

Inside the ActiveRecord module, you can refer to this class as just Base, whereas outside the module, you’d refer to it as ActiveRecord::Base. You can add multiple classes, functions, and variables to any Ruby module.

(For those that are curious, ActiveRecord::Base is ActiveRecord’s equivalent to NSManagedObject. It’s the class you subclass from to make new ORM objects.)

I want this effect in Swift. Swift has something called modules, but those are really just frameworks. I know they can give you some potential compilation speedups, but making a Swift module is pretty high ceremony and involves a lot of configuration. I just want to type some code, and isolate some classes from some other classes.

This great Natasha the Robot post from a few months ago finally gave me the tools I needed to make Swift namespaces a reality.

She used an enum with no cases (because enums with no cases crucially can’t be initialized) and added static properties to the enum to give them a fake namespace.

enum ColorPalette {
    static let Red = UIColor(red: 1.0, green: 0.1491, blue: 0.0, alpha: 1.0)
    static let Green = UIColor(red: 0.0, green: 0.5628, blue: 0.3188, alpha: 1.0)
    static let Blue = UIColor(red: 0.0, green: 0.3285, blue: 0.5749, alpha: 1.0)
}

I want to take advantage of this syntax because I find that the features I write have a bunch of classes that all have the same prefix. For example, the authentication flow in an app might have lots of little components: AuthenticationCoordinator, AuthenticationData, AuthenticationFormView, AuthenticationFormConfiguration, AuthenticationFormField, and AuthenticationFormFieldConfiguration, as well other namespaced objects like SignupViewController and SignupView.

Some of these class names are starting to get pretty long! Since something just called FormField would pollute the global namespace, I have to tack on the “Authentication” prefix. I don’t want it to collide with any other form fields I might have in my app. If we wanted to take Natasha’s scoping pattern to the next level, we could make an Authentication enum.

enum Authentication { }

From there, we can extend it to add nested types:

extension Authentication {
	struct Data {
		let username: String
		let password: String
		//etc
	}

	class Coordinator {
		//implementation   	
	}
}

Inside the Coordinator class, we can just refer to Authentication.Data as simply Data (since they’re both inside the Authentication module). Outside the module, we’ll refer to it as Authentication.Data. This is exactly the behavior we want.

By adding one character of code (the period) for references outside the module, we get to drop a ton of characters when working with references inside the module. Further, having to add the prefix and the period explicitly will formalize all class names inside of the module. It’ll be super obvious when we’re trying to use these types from outside the module.

We can add more extensions across multiple files.

extension Authentication {
	class LoginViewController {
		//implementation   	
	}
}

A good way to use this pattern would be namespacing a view controller and its smarter view together.

enum Signup { }

//SignupViewController.swift
extension Signup {
	class ViewController {
		func loadView() {
			self.view = View()
		}
		
		//etc
	}
}

//SignupView.swift
extension Signup {
	class View {
	    //etc
	}
}

You can also nest these modules, like Natasha shows in her post.

extension Authentication {
	enum Form {
		class View {
		    
		}
	}
}

When nesting, if you want to move things to a different file, you’ll have to use a slightly different syntax:

// create the new triply-nested namespace
extension Authentication.Form {
	enum Field { }
}

// in a different file
extension Authentication.Form.Field {
	struct Data {
				
	}
				
	class View {
			
	}
}

Because Swift doesn’t allow you to use the extension keyword outside of the file scope, when nesting, you have to use the dot-syntax to access your nested namespace.

There’s one big downside to abusing an enum type like this. The protocol keyword, like the extension keyword, is limited to the file scope only, so you can’t declare any protocols inside your namespace.

It’s a bit of a heretical approach to structuring code, but many new ideas seem heretical at first. Ideally, Swift would add a module keyword. But barring that, they could make protocols work in enums and I’d be happy to use the enum trick to fake namespaces.

Last year, in the run up to WWDC, I published a post called Why I don’t write Swift. Since then, I’ve shipped two major contracting projects, both in Swift, over the last six months. With this newfound experience in small to medium Swift codebases, I have some new observations and comments on writing codebases or large portions thereof in Swift.

It’s been a big year. Besides Swifts 2.0, 2.1, and 2.2, we’ve also seen the open-sourcing of Swift, a roadmap with public timelines, and plenty of open discussion about the future of the language. I’m hopeful about it for sure, and I have little doubt that it’ll be the only language that we write iOS and Mac apps in.

Primarily, the big thing I got wrong last year was that Swift is just plain fun. This weekend, I had the pleasure of helping a friend with code-review. His project is completely in Objective-C, and our code review session reminded me how rough the rough edges of that language are, especially after spending any time in Swift. Listening to myself try to explain the difference between the NSNumber, int, and NSInteger types made me long for Swift. While helping him write new code, I kept forgetting to include semicolons, missed typed arrays greatly, and wish I’d had map and filter handy. Swift has plenty of its own quirks and complexities, but it rounds off so many of Objective-C’s rough edges that writing code in it becomes joyful. I love enums, I love protocols, and I love optionals.

Despite this newfound revelation, I still think the prudent choice is to continue writing apps in Objective-C. Those who are fully on board with Swift commonly reply: every line of Objective-C you write is a legacy. While this is true, Objective-C code will still be viable for at least another five years, and probably won’t stop working for closer to 10 or 15. This is based the fact that every one of Apple’s OSes is written in it, as well as the frameworks themselves. (How long did Carbon code work for? How long before Finder was rewritten in Cocoa?)

However, your Swift 2.2 project is also going to become legacy code, and that transition will happen this September. Your migration will be a bloodbath, and it will have to happen in one fell swoop (including your dependencies!) because of a lack of ABI compatibility. Latent bugs will creep in from the migrator, and you’ll have to keep your swift-3 branch updated with regular, messy merges. In the end, git bisect will stop working, and your compile times will still be awful.

Despite this brutal reality, every client I’ve talked to wants their app in pure Swift. I’m happy to give them my professional advice, which is that it’ll cause more problems that it’ll solve. I don’t fight that hard, though, because I know the industry is moving in a Swifty direction, and there’s not really anything that one person can do about it. When I’m done on the project, the next developer that comes on board would just scoff and overrule any restraint I brought to the project. He or she would probably also curse me while they’re at it.

My post-WWDC takeaway last year was:

My new plan is that once Swift is source compatible with previous versions, the next new app I write after that will be all Swift. I don’t want my code to break when I go back in git, and I don’t want to deal with the context switching of having Objective-C and Swift in one app.

This basically still seems right to me. As clients want it, I’m happy to write Swift. That decision isn’t hard, given that I enjoy it so much, and given that it won’t hurt to keep my skills sharp. My own projects will probably stay in Objective-C, at least until ABI compatibility, and probably until source compatibility.

Unlike last year, we already know what’s coming in Swift 3, and what else is in the pipeline. Despite my short-term hesitance and despite the language’s seemingly slow pace of advancement, I think that Swift in general is on the right track. Getting ABI resilience right is important, and shouldn’t be rushed. The features in the pipeline will solve real pain points that users have (you’ll note I’m currently ignoring the static vs dynamic brouhaha, but I would love to write a post about it soon). The long-term future of Swift is bright, and I can’t wait to get there.

In Protocol-Oriented Networking, I laid out a protocol for defining requests, and I used default implementations to add defaults and extra behavior to each Request. First, let’s take a look at that protocol.

protocol Request {
    var baseURL: NSURL? { get }
    var method: String { get }
    var path: String { get }
    var parameters: Dictionary<String, String> { get }
    var headers: Dictionary<String, String> { get }
}

I used a protocol extension with default implementations to prevent the user from having to provide the obvious defaults.

extension Request {
    var method : String { return "GET" }
    var path : String { return "" }
    var parameters : Dictionary<String, String> { return Dictionary() }
    var headers : Dictionary<String, String> { return Dictionary() }
}

The only thing that’s necessary to implement a complete Request is a baseURL. Everything else has a default. When I wrote the blog post, I (correctly) identified this as “pretty much the template method pattern”.

With Swift 2, however, while we could continue to use decoration to wrap our data with new functionality, we’ve been given a new power with protocol extensions. Protocol extensions let us add concrete methods to a protocol that are dependent on the abstract methods in that protocol. It’s a form of the template method pattern, but one that doesn’t rely on inheritance.

Protocols with default implementations are a much nicer and more compiler-friendly version of the template method pattern. Functionally, protocols with default implementations let you provide defaults, mark the “abstract” methods as abstract, and override the non-abstract ones as needed in the concrete classes. The compiler gives you an affordance for everything that you would normally user documentation or run-time errors for.

After this point, I feel like the post went awry. I added two more functions, one for building an NSURLRequest and one for initiating that request.

extension Request {
    func buildRequest() -> NSURLRequest? {
        // build a URL for the request
        // encode the parameters as JSON
        // etc
        // return the request
    }
    
    func sendRequest(success success: (result: AnyObject) -> (), failure: (error: ErrorType) -> ()) {
        // send the request
        // parse the result
        // fire the blocks on success and failure
    }
}

This extension is different and fundamentally worse than the previous extension, for a few reasons.

It locks me into building requests a specific way. What if I don’t want to encode the parameters in JSON? What if I have extra parameters to encode in the body, like in a multi-part request? What if I want to add a parameter, like in a paginatable request? What if I want to add headers for the authorization? What if I want to have the sendRequest() function method return a Promise, or conditionally handle the sending through another library?

I could override the buildRequest() method for specific requests, and do custom stuff in them on a per-request basis. I don’t want to do that, primarily because of the static dispatch of the methods buildRequest() and sendRequest(). Their exeuction is dependent on which type the compiler thinks they are at compile time. This issue is laid out well in this post. The behavior is highly counter-unintuitive.

I could also add more methods on Request, like buildJSONRequest(), buildURLEncodedRequest(), buildMultipartRequest(), but this would be very unelegant and unwieldy.

Ultimately, I want Request to be dumb data. It shouldn’t know how to build an NSURLRequest. That’s why the request construction code is in an extension. With Swift, however, if you put something in a protocol extension, you’re locked into it. You should use only extensions with default behavior when you expect to need that data or behavior every time.

Decoration in Swift

To solve our problem, we need something like decoration for Swift. We could use normal decoration, but Swift fortunately lets us do a similar thing without having to define new concrete types.

Taking inspriation from the Swift standard library (and from Olivier Halligon), we can just add a lot more protocols. The implementing object then decides which of those it wants to “conform to” and take behavior from. Let’s take a look at an example.

Let’s define a protocol called ConstructableRequest. It itself conforms to Request, and provides a method called buildRequest()

protocol ConstructableRequest: Request {
    func buildRequest() -> NSURLRequest?
}

From that, we can add another, more “concrete” protocol for constructing a request with a JSON body.

protocol JSONConstructableRequest: ConstructableRequest { }
extension JSONConstructableRequest {
    func buildRequest() -> NSURLRequest? {
        // build a URL for the request
        // encode the parameters as JSON
        // etc
        // return the request
    }
}

This protocol would actually contain an implementation of buildRequest for requests that will have a JSON body. Then, we take advantage of this new protocol in a third one called SendableRequest:

protocol SendableRequest: ConstructableRequest { }
extension SendableRequest {
    func sendRequest(success success: (string: String) -> (), failure: (error: ErrorType) -> ()) {
        // send the request
        // parse the result
        // fire the blocks on success and failure
    }
}

SendableRequest relies only on ConstructableRequest. It doesn’t know how the request will be constructed, just that it will have access to a function that will build an NSURLRequest. When we go to define our request, we just mark which protocols (and thus which behaviors) we want:

struct ZenRequest: Request, JSONConstructableRequest, SendableRequest {
    let baseURL = NSURL(string: "https://api.github.com/")
    let path: String = "zen"
}

By choosing which protocols to conform to, we can add behavior in a dynamic fashion. Protocols can also be conformed to after the fact as well, so if you had a different sending mechanism, you could adapt your concrete request to that protocol after its definition:

extension ZenRequest: PromisedRequest { }

where PromisedRequest is some protocol that takes a SendableRequest and makes it return a Promise instead of having completion blocks.

When I started this post, I thought I would end up with regular decoration again. I thought I would end up with some code like the Objective-C version:

SendableRequest(request: ZenRequest()).sendRequest(...

Writing the code this way would require us to to use the SendableRequest keyword at every call-site, which is definitely worse than the protocol way: just declare it once at the definition of the request struct. Swift’s protocols let you do decoration in a weird and new way, and I think I like it.

Type Safety

If you want to add type-safe parsing to this scheme, sometimes you hit the annoying “Protocol X can only be used as a constraint because it has Self or associated type requirements” compiler error. I’m still wrapping my head around why it happens sometimes and doesn’t other times. I will have to read Russ Bishop’s post a few more times, I think.

To avoid the compiler error, make a new protocol with an associated type:

protocol ResultParsing {
    associatedtype ParsedType
    func parseData(data: NSData) -> ParsedType?
}

Like JSON parsing, you can now make a “concrete version” of this protocol, using a specific type in place of ParsedType:

protocol StringParsing: ResultParsing { }

extension StringParsing {
    func parseData(data: NSData) -> String? {
        return NSString(data: data, encoding: NSUTF8StringEncoding) as? String
    }
}

Then, make SendableRequest use the abstract version of the new protocol:

protocol SendableRequest: ConstructableRequest, ResultParsing { }
extension SendableRequest {
    func sendRequest(success success: (result: ParsedType) -> (), failure: (error: ErrorType) -> ()) {
        // send the request
        // parse the result
        // fire the blocks on success and failure
    }
}

Notice how SendableRequest returns ParsedType now. (You can take a look at the playground at the bottom of the post for an exact implementation.)

Finally, in your request, just declare which parser you want to use, as a protocol conformance.

struct ZenRequest: Request, JSONConstructableRequest, SendableRequest, StringParsing {
    let baseURL = NSURL(string: "https://api.github.com/")
    let path: String = "zen"
}

Small, reusable components.

JSON

You can make your ResultParsing types do anything. For example, given some JSONConstructable protocol:

protocol JSONConstructable {
    static func fromData(data: NSData) -> Self?
}

struct User: JSONConstructable {
    static func fromData(data: NSData) -> User? {
        return User()
    }
}

struct Tweet: JSONConstructable {
    static func fromData(data: NSData) -> Tweet? {
        return Tweet()
    }
}

You can then create a JSONParsing protocol that works much in the same way as the StringParsing protocol, but with an associated type parameter, JSONType.

protocol JSONParsing: ResultParsing {
    associatedtype JSONType: JSONConstructable
    func parseData(data: NSData) -> JSONType?
}

extension JSONParsing {
    func parseData(data: NSData) -> JSONType? {
        return JSONType.fromData(data)
    }
}

To use it, just conform to JSONParsing and add a typealias in your request:

struct UserRequest: Request, JSONConstructableRequest, SendableRequest, JSONParsing {
    let baseURL = NSURL(string: "https://api.khanlou.com/")
    let path: String = "users/1"
    
    typealias JSONType = User
}

Playground

I’ve made a playground with all the code from this post.

Protocols in Swift are very powerful, especially because they can include default implementations as of Swift 2.0. However, because of its static nature, protocol-oriented programming can still lock you in to certain patterns. Protocols should be very small, ideally containing only one responsibility each.

Swift’s standard library itself is built on a lot of the these concepts, with protocols like SequenceType and IntegerLiteralConvertible. The standard library uses these protocols to manage its internals. Conforming to your own structs and classes to these protocols nets you syntax features and functions like map for free. Taking inspriation from the standard library in our own protocol design helps us get to protocol nirvana.