App Development

Protocol-Oriented Programming

protocol-oriented-programming blog-feature-image JW-510x295

One of the sessions at WWDC this year was entitled Protocol-Oriented Programming, and looked to introduce a new a set of Swift features as well as a new paradigm for programming in Swift that takes advantage of its value semantics. So what is it? And how does it actually change the way we think about programming?

What’s Not New

The talk opens by having an old programmer named Crusty complaining about Object-Oriented Programming, and longing for the old days of C compilers.

Let’s face it, we’ve all got a little Crusty in us, and even when presented with something as interesting as what we see in this talk, the Crusty in all of us has to compare it to what’s come before.

But that’s not a bad thing! While Protocol-Oriented Programming is presented as new and promising, it’s still beneficial to look at what it’s taking from other existing languages and concepts so we can understand it for ourselves, and in the broader context of programming.

Protocol Extensions - Although new to Objective-C and Swift programmers, Protocol extensions at their most basic are essentially abstract class methods from languages that allow those (abstract in Java and C#, or pure-virtual functions in C++). One of the more interesting parts about the methods declared in protocol extensions though, is that methods not required in the protocol do not perform dynamic dispatch, distinct from the approach in Objective-C which has dynamic dispatch everywhere.

This is simultaneously incredibly powerful and a potential space for a lot of bugs if you’re not careful. The main place where this is an issue is when a protocol extension creates an extension point that is not required by the original protocol. Because this is not a dynamic dispatch scenario, the function called is dependant on the type you’re holding, as in the following example:

blog-post-image object-oriented-programming JW

In the above example, because “walk” isn’t defined in the protocol, the extension method takes precedence over the dynamic dispatch to the implementing struct. This is true of classes as well.

Recommendations on Value Types - Though touched on in another talk, the speaker here reiterates some recommendations about how to treat any value type you create. This is generally not new. C++ Best Practices basically recommend the same when implementing a class that can be thought of as a value type, and C# best practices also recommend almost the exact same policies on structs or immutable classes. In general if it’s a value type, or it’s going to be used as a value type, it should be copyable, hashable and equateable / comparable.

What Is New

Self Requirements - Although you can kind of, sort of hack this in other type safe languages, (including a curious way to do it in C#), self requirements are a great way to specify that a specific generic function can only be applied to the same type the function is being called on or that is applying the protocol.

Protocol Extension - While the concept of protocol extension isn’t really new, some specifics about how it can be implemented in Swift are new, if not entirely alien. For example, protocol extensions can use the same constraints that are applied to generics, selectively extending for specific types that conform to the protocol. The example given in the talk was for comparing Drawables:  

[swift 2.0 code]
extension Drawable where Self : Equatable {
func isEqualTo(other: Drawable) -> Bool {
if let o = other as? Self { return self == o }
return false
}

Retroactive Modeling - Because of the way protocol extensions work, you can now apply the implementation of a prototype to an existing type via a category or extension. This means there’s no need to make wrapper types just to serve as a pass through from one type to the other. In the talk, they show turning a CGContext into a Renderer. Where previously you would potentially have to create a CGContextRenderer, this is now unnecessary.

Magic is in the Combination While there’s a lot here that’s not new, and a lot here that is new, the magic is in the combination of the paradigms and features of Swift. They allow you to extend types without inheritance, in a way that still forces them to conform to a specific interface specific to your app.

In OO heavy languages, like Java, there is frequently an over-use of weirdly named, sometimes oddly-specific interfaces and abstract classes. This is usually in an effort to make sure many points of the app are customizable or injectable.

With Protocol Extensions and Retroactive modeling, there’s no longer the need to try to think of or account for all of these extension points since almost any type, both structs and classes, can be extended via protocols. This allows us to now think of data on it’s own, and attach functional blocks to that data without creating a mess of interlocking interfaces, shared state or dependencies.

Quickstart-Guide-to-Kotlin-Multiplatform

A Quick Start Guide to Kotlin Multiplatform

Kotlin Multiplatform, though still experimental, is a great up-and-coming solution...

Read the article