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.
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.
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.
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!
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.
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:
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:
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 }
`else`(error)
}
}
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()
db.prefetch()
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 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!
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 {
print(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(optional1.map({ $0.count }) ?? 0)
print(optional2.map({ $0.count }) ?? 0)
// With
print(optional1.map({ $0.count }, default: 0)) // prints 10
print(optional2.map({ $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:
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) })
.or(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, user.id < 1000 { aUser.upgradeToPremium() }
// Using `filter`
user.filter({ $0.id < 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:
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? database.software(for: 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? database.software(for: 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:
Less Code
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.
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:
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 Bookmarkstruct. 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.
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:
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 {
print(anAssociatedExample.value)
}
if let anAssociatedExample = aNormalExample as? StringExample {
print(anAssociatedExample.value)
}
}
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 {
fatalError()
}
var processorCount: Int {
fatalError()
}
}
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 classprivate 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 Computerprotocol 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:
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>:
AnyComputerBase<ConcreteComputer.ProcessorType>
{
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>:
AnyComputerBase<ConcreteComputer.ProcessorType>
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 typeProcessorType to the abstract superclass. In a simpler explanation, this is what happens (in a mock language):
Computer<CPU>
AnyComputerBase<Processor: CPU>: Computer<CPU> where Computer.CPU = Processor
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 Computerprotocol. 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:
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 ConcreteComputer 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 ConcreteComputer.
Then we return the implementations of the contents of the box (i.e. the actual ConcreteComputer) 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.
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:
#!/bin/bash
# Amount of seconds to wait between measures
n=1
# Limit memory consumption to this many megabytes before killing the process
x=5000
name="SourceKitService"
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
continue
fi
if [ "$mem" -gt $x ]; then
echo "Killing $name pid $pid with mem $mem"
kill -9 $pid
sleep 5
fi
sleep $n
done
To use this just paste that code into a file (say sourcekill.sh) and do:
Following sage advice I received from John Sundell half a year ago (I am a slow learner) I will try to write about smaller pieces instead of focusing on longform content. This should make it easier to update appventure more often. Thanks John!.
Today, I'll write about value types: Value types are a very useful addition to Swift. Objective-C did offer C struct types and (obviously) classical value types such as numbers, but Swift goes way beyond that by allowing us to also define more complex structures such as Array, Set, or Dictionary as value types. One of the best properties of value types is that they can easily be compared given that they're values:
let one = [1, 2, 3]
let two = [1, 2, 3]
print(one == two) // returns true
This way of easily comparing arrays is something we can use to implement a simple difference detection algorithm without using more heavy-weight solutions. Imagine you have a simple app that downloads a list of entries from a server and displays them in a table view. Once a minute you download a new list and reload the table view. This is not a particularly nice solution as you're reloading the table view even when there're no changes. If your data is defined as a struct and you implement the Equatable protocol, then you can simply use the equality operator to see if the table view needs to be reloaded:
struct Data: Equatable {
let username: String
let userid: Int
static func ==(lhs: Data, rhs: Data) -> Bool {
return lhs.username == rhs.username && lhs.userid == rhs.userid
}
}
let oldData: [Data] = currentData()
let newData: [Data] = retrieveNewData()
guard oldData != newData else {
return
}
updateData(with: newData)
However, it may be that your data is modelled using struct types, but that they're very complex and change often. So you've never implemented Equatable. Then you have three different options:
Use Krzysztof Zabłocki's Sourcery which is a meta programming framework that allows you to auto generate things like Equatable conformance for your types (and much more).
This I will explain in more detail as it is also a pattern that you can use if your data is modelled using class types.
The idea here is to store just the absolutely necessary information in a seperate difference detection cache. Imagine the following data model:
final class Story {
let story_id: Int
let views: Int
let last_updated: TimeInterval
let description: String
}
In this example, a Story will never change its id and description. In order to create a simple cache, we can now just use the information we absolutely need to determine a change and store them in tuples. Tuples with up to 6 elements will automatically generate Equatable conformance:
This is a simple solution that leverages value types to give us an easy solution for comparing sets of data. However, if you also need to determine insertions, deletions and moves then you can still do so with value types, but you need a proper diff algorithm such as Dwifft.
Nevertheless, for many simpler use cases it is good to remember that we can easily build a comparison cache of tuples or structs to determine general changes to data.
{:description "Documenting my technology research",
:projects ({:project "Sarbatka", :link "/electronic-music.html"}),
:postlist
({:title "Blogstrapped.",
:url "/2011/12/01/blogstrapped/",
:tags "entrepeneurship blog",
:keyword-tags (:entrepeneurship :blog),
:date "Thu, 1 Dec 2011",
:keywords "entrepeneurship videro fear unknown stylemac",
:keyword-keywords
(:entrepeneurship :videro :fear :unknown :stylemac)}
{:title "Fast NSDictionary traversal in Objective-C",
:url "/2011/12/07/fast-nsdictionary-traversal-in-objective-c/",
:tags "objective-c ios cocoa",
:keyword-tags (:objective-c :ios :cocoa),
:date "Wed, 7 Dec 2011"}
{:title "How the iPad can improve focus",
:url "/2011/12/09/how-the-ipad-can-improve-focus/",
:tags "opinion",
:keyword-tags (:opinion),
:date "Fri, 9 Dec 2011"}
{:title "Use VIM as an Xcode alternative",
:url "/2013/01/29/use-vim-as-xcode-alternative-ios-mac-cocoa/",
:tags "cocoa objective-c ios",
:keyword-tags (:cocoa :objective-c :ios),
:date "Tue, 29 Jan 2013"}
{:title "Now Running Clojure",
:url "/2014/01/20/now-running-clojure/",
:tags "clojure blog",
:keyword-tags (:clojure :blog),
:date "Mon, 20 Jan 2014"}
{:title
"Debugging entitlement issues in Maps, iCloud, In-App, Keychain, or GameCenter",
:url
"/2014/01/21/debugging-entitlement-maps-icloud-gamecenter-issues/",
:tags "ios cocoa",
:keyword-tags (:ios :cocoa),
:date "Tue, 21 Jan 2014",
:keywords "ios cocoa entitlements",
:keyword-keywords (:ios :cocoa :entitlements)}
{:title
"Clojure/Enlive Static Site Generator that keeps your HTML intact",
:url
"/2014/01/22/clojure-enlive-static-site-generator-that-keeps-html-intact/",
:tags "blog clojure",
:keyword-tags (:blog :clojure),
:date "Wed, 22 Jan 2014",
:keywords "clojure static site generator jekyll html enlive",
:keyword-keywords
(:clojure :static :site :generator :jekyll :html :enlive)}
{:title "Finding a good URL Partitioning Scheme for PostgreSQL",
:url "/2014/01/24/finding-url-partitioning-scheme-postgres/",
:tags "postgresql clojure",
:keyword-tags (:postgresql :clojure),
:date "Fri, 24 Jan 2014",
:keywords "clojure postgresql partitioning scheme",
:keyword-keywords (:clojure :postgresql :partitioning :scheme)}
{:title "An Emacs Lisp tooling tutorial, writing a bulk mailer",
:url "/2014/01/29/emacs-lisp-tooling-tutorial-writing-bulk-mailer/",
:tags "emacs",
:keyword-tags (:emacs),
:date "Wed, 29 Jan 2014",
:keywords
"emacs lisp bulk mailer tutorial email vim vimscript evil",
:keyword-keywords
(:emacs :lisp :bulk :mailer :tutorial :email :vim :vimscript :evil)}
{:title
"Creating a Swift syntax extension: the Lisp 'cond' function",
:url "/2014/06/08/writing-simple-syntax-extensions-in-swift/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Sun, 8 Jun 2014",
:keywords
"clojure lisp swift cond syntax macro extension cocoa ios feature",
:keyword-keywords
(:clojure
:lisp
:swift
:cond
:syntax
:macro
:extension
:cocoa
:ios
:feature)}
{:title "Swift optionals made simple",
:url "/2014/06/13/swift-optionals-made-simple/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Fri, 13 Jun 2014",
:keywords
"lisp swift optional scala simple optionals switch chaining feature",
:keyword-keywords
(:lisp
:swift
:optional
:scala
:simple
:optionals
:switch
:chaining
:feature)}
{:title "Generic method overloading by protocol in Swift",
:url "/2015/06/17/swift-method-overloading-by-protocol/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Wed, 17 Jun 2015",
:keywords
"swift optional simple overloading method protocol extensions generics feature",
:keyword-keywords
(:swift
:optional
:simple
:overloading
:method
:protocol
:extensions
:generics
:feature)}
{:title "Using try / catch in Swift with asynchronous closures",
:url "/2015/06/19/swift-try-catch-asynchronous-closures/",
:tags "swift ios",
:keyword-tags (:swift :ios),
:date "Fri, 19 Jun 2015",
:keywords "swift try catch errortype closure async result feature",
:keyword-keywords
(:swift :try :catch :errortype :closure :async :result :feature)}
{:title "Debugging advanced compilation errors in ClojureScript",
:url "/2015/07/02/debugging-clojurescript-advanced-compilation/",
:tags "clojure",
:keyword-tags (:clojure),
:date "Thu, 2 Jul 2015",
:keywords "debugging clojure clojurescript externs",
:keyword-keywords (:debugging :clojure :clojurescript :externs)}
{:title "Tuples in Swift, Advanced Usage and Best Practices",
:url "/2015/07/19/tuples-swift-advanced-usage-best-practices/",
:tags "swift",
:keyword-tags (:swift),
:date "Sun, 19 Jul 2015",
:keywords "swift tuples generics feature",
:keyword-keywords (:swift :tuples :generics :feature)}
{:title "Match Me if you can: Swift Pattern Matching in Detail.",
:url "/2015/08/20/swift-pattern-matching-in-detail/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Thu, 20 Aug 2015",
:keywords
"feature lisp swift optional scala simple optionals switch chaining for pattern matching clojure haskell",
:keyword-keywords
(:feature
:lisp
:swift
:optional
:scala
:simple
:optionals
:switch
:chaining
:for
:pattern
:matching
:clojure
:haskell)}
{:title "Optional throw via try? in Swift 2 beta 6",
:url "/2015/08/25/optional-throw-swift/",
:tags "swift",
:keyword-tags (:swift),
:date "Tue, 25 Aug 2015",
:keywords
"swift error throw result either rethrow try syntax swift2",
:keyword-keywords
(:swift
:error
:throw
:result
:either
:rethrow
:try
:syntax
:swift2)}
{:title "Getting your iPhone 6s Chip Foundry from Swift",
:url "/2015/09/30/getting-iphone6s-foundry-from-swift/",
:tags "swift",
:keyword-tags (:swift),
:date "Wed, 30 Sep 2015",
:keywords
"swift iphone6s iphone tsmc samsung gestalt private api foundation",
:keyword-keywords
(:swift
:iphone6s
:iphone
:tsmc
:samsung
:gestalt
:private
:api
:foundation)}
{:title "Advanced & Practical Enum usage in Swift",
:url "/2015/10/17/advanced-practical-enum-examples/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 17 Oct 2015",
:keywords
"feature swift enum algebraic caseclass union case switch pattern simple practical advanced example",
:keyword-keywords
(:feature
:swift
:enum
:algebraic
:caseclass
:union
:case
:switch
:pattern
:simple
:practical
:advanced
:example)}
{:title "The Swift Reflection API and what you can do with it",
:url "/2015/10/24/swift-reflection-api-what-you-can-do/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 24 Oct 2015",
:keywords
"feature swift reflection struct class displayType mirror api reflecting any anyobject",
:keyword-keywords
(:feature
:swift
:reflection
:struct
:class
:displayType
:mirror
:api
:reflecting
:any
:anyobject)}
{:title "Reduce all the things",
:url "/2015/11/30/reduce-all-the-things/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Mon, 30 Nov 2015",
:keywords
"feature swift reduce map filter group partition split interpose chunk functional programming flatMap",
:keyword-keywords
(:feature
:swift
:reduce
:map
:filter
:group
:partition
:split
:interpose
:chunk
:functional
:programming
:flatMap)}
{:title
"Swift Package Manager: Create and Use a X11 package on Linux",
:url "/2015/12/08/swift-ubuntu-x11-window-app/",
:tags "swift linux",
:keyword-tags (:swift :linux),
:date "Tue, 8 Dec 2015",
:keywords "linux x11 swift libx11 xserver xorg",
:keyword-keywords (:linux :x11 :swift :libx11 :xserver :xorg)}
{:title "Hirundo: Comfortably follow Swift Mailing Lists on OSX",
:url "/2016/02/02/hirundo-mac-app-swift-mailing-lists/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Tue, 2 Feb 2016",
:keywords
"swift mac cocoa mailing list swift-dev swift-eveolution swift-users reading macosx",
:keyword-keywords
(:swift
:mac
:cocoa
:mailing
:list
:swift-dev
:swift-eveolution
:swift-users
:reading
:macosx)}
{:title "Three tips for concise Swift using the Guard statement",
:url "/2016/03/29/three-tips-for-clean-swift-code/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Tue, 29 Mar 2016",
:keywords
"swift mac cocoa guard let enum pattern matching patterns",
:keyword-keywords
(:swift :mac :cocoa :guard :let :enum :pattern :matching :patterns)}
{:title "Using Git Hooks to prevent commiting test code",
:url "/2016/04/04/prevent-accidental-test-code-commits/",
:tags "git",
:keyword-tags (:git),
:date "Mon, 4 Apr 2016",
:keywords "git hook commit debug test code",
:keyword-keywords (:git :hook :commit :debug :test :code)}
{:title
"Force optionals in multi-unwrapped \"guard let\" or \"if let\"",
:url
"/2016/04/14/force-optionals-in-guard-or-let-optional-binding/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Thu, 14 Apr 2016",
:keywords
"swift guard let unwrap bind binding unwrapped optional some none optionals",
:keyword-keywords
(:swift
:guard
:let
:unwrap
:bind
:binding
:unwrapped
:optional
:some
:none
:optionals)}
{:title "Raw value initializers for enums with associated types",
:url "/2016/04/23/associated-types-enum-raw-value-initializers/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 23 Apr 2016",
:keywords
"swift optional enum raw value initializers associated type",
:keyword-keywords
(:swift
:optional
:enum
:raw
:value
:initializers
:associated
:type)}
{:title "SwiftWatch",
:url "/2016/04/28/swiftwatch/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Thu, 28 Apr 2016",
:keywords
"swift hackernews reddit designernews lamernews socialnews swiftlang programming community post vote comment",
:keyword-keywords
(:swift
:hackernews
:reddit
:designernews
:lamernews
:socialnews
:swiftlang
:programming
:community
:post
:vote
:comment)}
{:title "Data in Swift 3 parsing a Doom WAD File",
:url "/2016/07/15/swift3-nsdata-data/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Fri, 15 Jul 2016",
:keywords "swift doom wad lumps data nsdata swift3 binary bytes",
:keyword-keywords
(:swift :doom :wad :lumps :data :nsdata :swift3 :binary :bytes)}
{:title "Value Types for Simple Difference Detection",
:url "/2017/09/30/value-types-for-simple-difference-detection/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 30 Sep 2017",
:keywords
"swift value types uitableview uicollectionview valuetypes struct class equatable tuple",
:keyword-keywords
(:swift
:value
:types
:uitableview
:uicollectionview
:valuetypes
:struct
:class
:equatable
:tuple)}
{:title "Taming SourceKitService for Less Xcode Memory Consumption",
:url "/2017/10/08/taming-sourcekitd/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sun, 8 Oct 2017",
:keywords "xcode sourcekit swift SourceKitService",
:keyword-keywords (:xcode :sourcekit :swift :SourceKitService)}
{:title "Patterns for Working With Associated Types",
:url "/2017/12/10/patterns-for-working-with-associated-types/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sun, 10 Dec 2017",
:keywords
"swift protocol protocols associated associatedtype typealias pattern pat",
:keyword-keywords
(:swift
:protocol
:protocols
:associated
:associatedtype
:typealias
:pattern
:pat)}
{:title "Useful Optional Extensions",
:url "/2018/01/10/optional-extensions/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Wed, 10 Jan 2018",
:keywords "swift protocol optional optionals extensions",
:keyword-keywords
(:swift :protocol :optional :optionals :extensions)}
{:title "Expanding Swift's Reach",
:url "/2018/05/03/expanding-swifts-reach/",
:tags "swift linux",
:keyword-tags (:swift :linux),
:date "Thu, 3 April 2018",
:keywords "swift linux server opensource",
:keyword-keywords (:swift :linux :server :opensource)}),
:tags
"benedikt, c, clojure, clojurescript, cocoa, html, ios, javascript, mac, objective-c, photodesk, research, stylemac, terhechte",
:template "default.clj",
:title "Appventure",
:author "Benedikt Terhechte",
:categories
({:tag "blog", :url "/tags/blog/index.html", :count 3}
{:tag "clojure", :url "/tags/clojure/index.html", :count 4}
{:tag "cocoa", :url "/tags/cocoa/index.html", :count 20}
{:tag "emacs", :url "/tags/emacs/index.html", :count 1}
{:tag "entrepeneurship",
:url "/tags/entrepeneurship/index.html",
:count 1}
{:tag "git", :url "/tags/git/index.html", :count 1}
{:tag "ios", :url "/tags/ios/index.html", :count 21}
{:tag "linux", :url "/tags/linux/index.html", :count 2}
{:tag "objective-c", :url "/tags/objective-c/index.html", :count 2}
{:tag "opinion", :url "/tags/opinion/index.html", :count 1}
{:tag "postgresql", :url "/tags/postgresql/index.html", :count 1}
{:tag "swift", :url "/tags/swift/index.html", :count 23}),
:pager {:older "/latest-posts/5/"},
:blog-index true,
:watching nil,
:site-title "Appventure"}
({:keyword-tags (:swift :linux),
:tags "swift linux",
:date "Thu, 3 April 2018",
:footnotes nil,
:meta
{:title "Expanding Swift's Reach",
:keyword-tags (:swift :linux),
:tags "swift linux",
:keyword-keywords (:swift :linux :server :opensource),
:keywords "swift linux server opensource",
:summary
"How can we as a community help expanding the reach of Swift",
:description
"How can we as a community help expanding the reach of Swift",
:options "toc:nil"},
:content
"<p>\nI 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 <a href=\"https://www.tensorflow.org/community/swift\">recently announced Swift for Tensorflow</a>). \n</p>\n\n<blockquote>\n<p>\nMy goal for Swift has always been and still is total world domination. It’s a modest goal\n</p>\n<ul class=\"org-ul\">\n<li>Chris Lattner\n</li>\n</ul>\n</blockquote>\n\n<p>\n<a href=\"https://swift.org/blog/swift-4-1-released/\">With Swift 4.1's new generic features</a> and the upcoming <a href=\"https://swift.org/abi-stability/\">ABI stability in Swift 5</a>, 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.\n</p>\n\n<p>\nI'd also like have a brief look at Swift's <b>competition</b> 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 <sup><a id=\"fnr.1\" name=\"fnr.1\" class=\"footref\" href=\"#fn.1\">1</a></sup>. By observing their take on the issue we can see where Swift stands in comparison, and what we can do.\n</p>\n\n<div id=\"outline-container-sec-1\" class=\"outline-2\">\n<h2 id=\"sec-1\"><span class=\"section-number-2\">1</span> System Packages</h2>\n<div class=\"outline-text-2\" id=\"text-1\">\n<p>\nSwift 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 <a href=\"https://vapor.codes/\">Vapor</a> or <a href=\"http://kitura.io/\">Kitura</a>, and they're doing a fantastic job of extending Swift's into the web development realm. \n</p>\n\n<p>\nHowever, 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.\n</p>\n\n<p>\nIn line with Swift's 4.1 release, <a href=\"https://news.ycombinator.com/item?id=16710895\">there was a thread on Hacker News discussing the language</a>. I've read the entire thread multiple times due to the fact that the answers were really interesting. What stood out to me was <a href=\"https://news.ycombinator.com/item?id=16710895\">the following comment</a>:\n</p>\n\n<blockquote>\n<p>\nThe set of libraries and supported OSes is a tiny dot comparable with the Go and Rust.\n…\nIf we start listing the kind of libraries used in distributed applications, database backends, Swift has hardly none of them.\n</p>\n</blockquote>\n\n<p>\nSo lets have a look at the others.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-2\" class=\"outline-2\">\n<h2 id=\"sec-2\"><span class=\"section-number-2\">2</span> Competitors</h2>\n<div class=\"outline-text-2\" id=\"text-2\">\n<p>\nThe 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.\n</p>\n\n<p>\nAlso, 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.\n</p>\n</div>\n\n<div id=\"outline-container-sec-2-1\" class=\"outline-3\">\n<h3 id=\"sec-2-1\"><span class=\"section-number-3\">2.1</span> Go</h3>\n<div class=\"outline-text-3\" id=\"text-2-1\">\n<p>\nGo 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.\n</p>\n\n<p>\nThe 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 <a href=\"https://github.com/avelino/awesome-go\">list just to observe how many libraries there are for any use case possibly imaginable</a>. \n</p>\n\n<p>\nIn short, if you want to develop anything system-based, almost all packages you might need as dependencies are readily available.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-2-2\" class=\"outline-3\">\n<h3 id=\"sec-2-2\"><span class=\"section-number-3\">2.2</span> Kotlin</h3>\n<div class=\"outline-text-3\" id=\"text-2-2\">\n<p>\nKotlin, 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 <a href=\"https://kotlinlang.org/docs/reference/native-overview.html\">there is Kotlin-Native which will make this more feasible in the future.</a> 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.\n</p>\n\n<p>\nKotlin 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).\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-2-3\" class=\"outline-3\">\n<h3 id=\"sec-2-3\"><span class=\"section-number-3\">2.3</span> Rust</h3>\n<div class=\"outline-text-3\" id=\"text-2-3\">\n<p>\nRust 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: \n</p>\n\n<p>\nA much better cross-platform story, a hard but rewarding memory management story (i.e. lifetimes / ownership) <a href=\"https://github.com/apple/swift/blob/master/docs/OwnershipManifesto.md\">that is thankfully also partially coming to Swift in the future</a>, support for <a href=\"https://rust-lang-nursery.github.io/rust-wasm/\">Webassembly</a> (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. <a href=\"https://github.com/rust-unofficial/awesome-rust\">Have a look at this list.</a>\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-2-4\" class=\"outline-3\">\n<h3 id=\"sec-2-4\"><span class=\"section-number-3\">2.4</span> Others</h3>\n<div class=\"outline-text-3\" id=\"text-2-4\">\n<p>\nThere're also D, Nim, Chrystal, Elixir, TypeScript, and obviously C++ itself but this post is already long enough as it is.\n</p>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-sec-3\" class=\"outline-2\">\n<h2 id=\"sec-3\"><span class=\"section-number-2\">3</span> What can we see</h2>\n<div class=\"outline-text-2\" id=\"text-3\">\n<p>\nSwift currently falls short in the area of system packages. This is also a chicken-egg problem:\n</p>\n\n<blockquote>\n<p>\nAs 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.\n</p>\n</blockquote>\n\n<p>\nTo 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):\n</p>\n\n<ul class=\"org-ul\">\n<li>Authentication\n</li>\n<li>Caching\n</li>\n<li>Concurrency\n</li>\n<li>Cloud Providers\n</li>\n<li>Command Line Argument Parsing\n</li>\n<li>Command Line UI\n</li>\n<li>Command Line Editors\n</li>\n<li>Compression\n</li>\n<li>Computations (i.e. BLAS)\n</li>\n<li>Cryptography\n</li>\n<li>Databases\n</li>\n<li>Data Processing\n</li>\n<li>Data Structures\n</li>\n<li>Data Visualization\n</li>\n<li>Date and Time\n</li>\n<li>Distributed Systems\n</li>\n<li>Email\n</li>\n<li>Encoding & Decoding\n</li>\n<li>Filesystems\n</li>\n<li>Image Processing\n</li>\n<li>Machine Learning\n</li>\n<li>Parsing\n</li>\n<li>Text Processing\n</li>\n<li>Virtualization\n</li>\n</ul>\n\n<p>\nIn 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.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-4\" class=\"outline-2\">\n<h2 id=\"sec-4\"><span class=\"section-number-2\">4</span> So, what can you do</h2>\n<div class=\"outline-text-2\" id=\"text-4\">\n</div><div id=\"outline-container-sec-4-1\" class=\"outline-3\">\n<h3 id=\"sec-4-1\"><span class=\"section-number-3\">4.1</span> Write libraries</h3>\n<div class=\"outline-text-3\" id=\"text-4-1\">\n<p>\nBefore 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.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-4-2\" class=\"outline-3\">\n<h3 id=\"sec-4-2\"><span class=\"section-number-3\">4.2</span> Rewrite Existing C libraries</h3>\n<div class=\"outline-text-3\" id=\"text-4-2\">\n<p>\nFor 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 ;-)\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-4-3\" class=\"outline-3\">\n<h3 id=\"sec-4-3\"><span class=\"section-number-3\">4.3</span> Care about Linux</h3>\n<div class=\"outline-text-3\" id=\"text-4-3\">\n<p>\nI 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.\n</p>\n\n<p>\nThis might also be easier than it sounds. <a href=\"https://hub.docker.com/r/ibmcom/swift-ubuntu/tags/\">There's a readily-available docker image for Swift 4.1</a>, so you can just run that in order to test your code.<sup><a id=\"fnr.2\" name=\"fnr.2\" class=\"footref\" href=\"#fn.2\">2</a></sup>. Alternatively, you can run <a href=\"https://www.virtualbox.org/\">Virtualbox</a> if you'd rather have a full running VM.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-4-4\" class=\"outline-3\">\n<h3 id=\"sec-4-4\"><span class=\"section-number-3\">4.4</span> Support Swift Package Manager</h3>\n<div class=\"outline-text-3\" id=\"text-4-4\">\n<p>\nIf you have a library already, try to always support the Swift Package Manager in addition to CocoaPods and Carthage.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-4-5\" class=\"outline-3\">\n<h3 id=\"sec-4-5\"><span class=\"section-number-3\">4.5</span> Work on Foundation</h3>\n<div class=\"outline-text-3\" id=\"text-4-5\">\n<p>\nAnother thing that is still difficult is that Swift for Linux's <a href=\"https://github.com/apple/swift-corelibs-foundation\">Foundation library</a> 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.\n</p>\n\n<p>\nThe easiest starter for this is to head over to the <a href=\"https://bugs.swift.org/secure/Dashboard.jspa\">Swift Jira</a> and search for Foundation bugs.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-4-6\" class=\"outline-3\">\n<h3 id=\"sec-4-6\"><span class=\"section-number-3\">4.6</span> Help out Foundation</h3>\n<div class=\"outline-text-3\" id=\"text-4-6\">\n<p>\nIf 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.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-4-7\" class=\"outline-3\">\n<h3 id=\"sec-4-7\"><span class=\"section-number-3\">4.7</span> Help the Linux editing experience</h3>\n<div class=\"outline-text-3\" id=\"text-4-7\">\n<p>\nLinux 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 ;)\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-4-8\" class=\"outline-3\">\n<h3 id=\"sec-4-8\"><span class=\"section-number-3\">4.8</span> Try Swift in San Jose</h3>\n<div class=\"outline-text-3\" id=\"text-4-8\">\n<p>\nIf 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: <a href=\"https://www.tryswift.co/events/2018/sanjose/\">The Try Swift San Jose</a>.\n</p>\n\n<blockquote>\n<p>\n…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!\n</p>\n</blockquote>\n\n<p>\n<a href=\"https://www.tryswift.co/events/2018/sanjose/\">Check it out</a>.\n</p>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-sec-5\" class=\"outline-2\">\n<h2 id=\"sec-5\"><span class=\"section-number-2\">5</span> I should be doing this</h2>\n<div class=\"outline-text-2\" id=\"text-5\">\n<p>\nI haven't had much time to do any open source work in the past 1.5 years because I was busy working on <a href=\"https://photodesk-app.com\">my own (closed source) project</a>, 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.\n</p>\n\n<p>\n<a href=\"https://twitter.com/terhechte\">Also, for any discussion on this article, head to Twitter.</a>\n</p>\n</div>\n</div>\n<div id=\"footnotes\">\n<h2 class=\"footnotes\">Footnotes: </h2>\n<div id=\"text-footnotes\">\n\n<div class=\"footdef\"><sup><a id=\"fn.1\" name=\"fn.1\" class=\"footnum\" href=\"#fnr.1\">1</a></sup> <p>I.e. WebAssembly</p></div>\n\n<div class=\"footdef\"><sup><a id=\"fn.2\" name=\"fn.2\" class=\"footnum\" href=\"#fnr.2\">2</a></sup> <p>I'm trying to write another blog post that explains this in much more detail</p></div>\n\n\n</div>\n</div>",
:keywords "swift linux server opensource",
:title "Expanding Swift's Reach",
:filename "2018-05-03-expanding-swifts-reach.org",
:id 910974610,
:url "/2018/05/03/expanding-swifts-reach/",
:javadate #inst "2018-05-02T22:00:00.000-00:00",
:keyword-keywords (:swift :linux :server :opensource)}
{:keyword-tags (:swift :cocoa :ios),
:tags "swift cocoa ios",
:date "Wed, 10 Jan 2018",
:footnotes nil,
:meta
{:feature-image
"/img-content/2018-01-10-optional-extensions-feature-image.jpg",
:title "Useful Optional Extensions",
:keyword-tags (:swift :cocoa :ios),
:tags "swift cocoa ios",
:keyword-keywords
(:swift :protocol :optional :optionals :extensions),
:keywords "swift protocol optional optionals extensions",
:summary
"Several helpful extensions to the Optional type in order to simplify using it.",
:description
"Several helpful extensions to the Optional type in order to simplify using it.",
:options "toc:nil"},
:content
"<!-- #+feature-image: /img-content/2018-01-10-optional-extensions-feature-image.jpg -->\n\n<p>\n<code>Optionals</code> 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 <code>Optional</code> language feature alone removes a whole category of bugs from the development process.\n</p>\n\n<p>\nHowever, the API surface of Swift's optional is rather limited. The <a href=\"https://developer.apple.com/documentation/swift/optional#topics\">Swift documentation lists just a couple</a> of methods / properties on <code>Optional</code> - if we ignore <code>customMirror</code> and <code>debugDescription</code>:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">var unsafelyUnwrapped: Wrapped { get } \nfunc map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U? \nfunc flatMap<U>(_ transform: (Wrapped) throws -> U?) rethrows -> U?\n</pre>\n</div>\n\n<p>\nThe 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 <a href=\"http://appventure.me/2014/06/13/swift-optionals-made-simple/\">optional chaining</a>, <a href=\"http://appventure.me/2015/08/20/swift-pattern-matching-in-detail/\">pattern matching</a>, <code>if let</code> or <code>guard let</code>. 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 <code>if let</code> statements.\n</p>\n\n<p>\nI'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 <code>Optional</code>. Below are 14 useful <code>Optional</code> 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.\n</p>\n\n\n<div id=\"outline-container-sec-1\" class=\"outline-2\">\n<h2 id=\"sec-1\"><span class=\"section-number-2\">1</span> Emptiness</h2>\n<div class=\"outline-text-2\" id=\"text-1\">\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">extension Optional {\n /// Returns true if the optional is empty\n var isNone: Bool {\n\treturn self == .none\n }\n\n /// Returns true if the optional is not empty\n var isSome: Bool {\n\treturn self != .none\n }\n}\n</pre>\n</div>\n\n<p>\nThose are the most basic additions to the optional type. The implementation could also use a <code>switch</code> pattern match instead, but the <code>nil</code> 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 <code>optional.isSome</code> feels much cleaner and less noisy than <code>if optional == nil</code>:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">// Compare\nguard leftButton != nil, rightButton != nil else { fatalError(\"Missing Interface Builder connections\") }\n\n// With\nguard leftButton.isSome, rightButton.isSome else { fatalError(\"Missing Interface Builder connections\") }\n</pre>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-sec-2\" class=\"outline-2\">\n<h2 id=\"sec-2\"><span class=\"section-number-2\">2</span> Or</h2>\n<div class=\"outline-text-2\" id=\"text-2\">\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">extension Optional {\n /// Return the value of the Optional or the `default` parameter\n /// - param: The value to return if the optional is empty\n func or(_ default: Wrapped) -> Wrapped {\n\treturn self ?? `default`\n }\n\n /// Returns the unwrapped value of the optional *or*\n /// the result of an expression `else`\n /// I.e. optional.or(else: print(\"Arrr\"))\n func or(else: @autoclosure () -> Wrapped) -> Wrapped {\n\treturn self ?? `else`()\n }\n\n /// Returns the unwrapped value of the optional *or*\n /// the result of calling the closure `else`\n /// I.e. optional.or(else: { \n /// ... do a lot of stuff\n /// })\n func or(else: () -> Wrapped) -> Wrapped {\n\treturn self ?? `else`()\n }\n\n /// Returns the unwrapped contents of the optional if it is not empty\n /// If it is empty, throws exception `throw`\n func or(throw exception: Error) throws -> Wrapped {\n\tguard let unwrapped = self else { throw exception }\n\treturn unwrapped\n }\n}\n\nextension Optional where Wrapped == Error {\n /// Only perform `else` if the optional has a non-empty error value\n func or(_ else: (Error) -> Void) {\n\tguard let error = self else { return }\n\t`else`(error)\n }\n}\n</pre>\n</div>\n\n<p>\nAnother abstraction on the <code>isNone / isSome</code> concept is being able to specify instructions to be performed when the invariant doesn't hold. This saves us from having to write out <code>if</code> or <code>guard</code> branches and instead codifies the logic into a simple-to-understand method. \n</p>\n\n<p>\nThis concept is so useful, that it is defined in three distinct functions.\n</p>\n</div>\n\n<div id=\"outline-container-sec-2-1\" class=\"outline-3\">\n<h3 id=\"sec-2-1\"><span class=\"section-number-3\">2.1</span> Default Value</h3>\n<div class=\"outline-text-3\" id=\"text-2-1\">\n<p>\nThe first one returns the wrapped value of the optional or a default value:\n</p>\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let optional: Int? = nil\nprint(optional.or(10)) // Prints 10\n</pre>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-sec-2-2\" class=\"outline-3\">\n<h3 id=\"sec-2-2\"><span class=\"section-number-3\">2.2</span> Default Closure</h3>\n<div class=\"outline-text-3\" id=\"text-2-2\">\n<p>\nThe second one is very similar to the first one, however it allows to return a default value from a closure instead.\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let optional: Int? = nil\noptional.or(else: secretValue * 32)\n</pre>\n</div>\n\n<p>\nSince this uses the <code>@autoclosure</code> parameter we could actually use just the second <code>or</code> 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.\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let cachedUserCount: Int? = nil\n...\nreturn cachedUserCount.or(else: {\n let db = database()\n db.prefetch()\n guard db.failures.isEmpty else { return 0 }\n return db.amountOfUsers\n})\n</pre>\n</div>\n\n<p>\nA really nice use case for <code>or</code> is code where you only want to set a value on an optional if it is empty:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">if databaseController == nil {\n databaseController = DatabaseController(config: config)\n}\n</pre>\n</div>\n\n<p>\nThis can be replaced with the much nicer:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">databaseController = databaseController.or(DatabaseController(config: config)\n</pre>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-sec-2-3\" class=\"outline-3\">\n<h3 id=\"sec-2-3\"><span class=\"section-number-3\">2.3</span> Throw an error</h3>\n<div class=\"outline-text-3\" id=\"text-2-3\">\n<p>\nThis 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 <code>Dictionary</code>) or by throwing an <code>Error</code>. Combining these two oftentimes leads to a lot of unnecessary line noise:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">func buildCar() throws -> Car {\n let tires = try machine1.createTires()\n let windows = try machine2.createWindows()\n guard let motor = externalMachine.deliverMotor() else {\n throw MachineError.motor\n }\n let trunk = try machine3.createTrunk()\n if let car = manufacturer.buildCar(tires, windows, motor, trunk) {\n return car\n } else {\n throw MachineError.manufacturer\n }\n}\n</pre>\n</div>\n\n<p>\nIn this example, we're building a car by combining internal and external code. The external code (<code>external_machine</code> and <code>manufacturer</code>) choose to use optionals instead of error handling. This makes the code unnecessary complicated. Our <code>or(throw:)</code> function makes this much more readable:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">func build_car() throws -> Car {\n let tires = try machine1.createTires()\n let windows = try machine2.createWindows()\n let motor = try externalMachine.deliverMotor().or(throw: MachineError.motor)\n let trunk = try machine3.createTrunk()\n return try manufacturer.buildCar(tires, windows, motor, trunk).or(throw: MachineError.manufacturer)\n}\n</pre>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-sec-2-4\" class=\"outline-3\">\n<h3 id=\"sec-2-4\"><span class=\"section-number-3\">2.4</span> Handling Errors</h3>\n<div class=\"outline-text-3\" id=\"text-2-4\">\n<p>\nThe code from the <b>Throw an error</b> section above becomes even more useful when you include the following free function that was proposed by <a href=\"https://github.com/doozMen\">Stijn Willems on Github</a>. Thanks for the suggestion!\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">func should(_ do: () throws -> Void) -> Error? {\n do {\n\ttry `do`()\n\treturn nil\n } catch let error {\n\treturn error\n }\n}\n</pre>\n</div>\n\n<p>\nThis free function (alternatively, you could make it a class method on optional) will perform a <code>do {} catch {}</code> block and return an error if and only if the closure `do` resulted in an error. Take, the following Swift code as an example:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">do {\n try throwingFunction()\n} catch let error {\n print(error)\n}\n</pre>\n</div>\n\n<p>\nThis 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:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">should { try throwingFunction) }.or(print($0))\n</pre>\n</div>\n\n<p>\nI feel that there're many situations where such a one-liner for error handling would be very beneficient.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-2-5\" class=\"outline-3\">\n<h3 id=\"sec-2-5\"><span class=\"section-number-3\">2.5</span> Map</h3>\n<div class=\"outline-text-3\" id=\"text-2-5\">\n<p>\nAs we saw above, <code>map</code> and <code>flatMap</code> 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 <code>map</code> that allow defining a default value similar to how the <code>or</code> variants above are implemented:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">extension Optional {\n /// Maps the output *or* returns the default value if the optional is nil\n /// - parameter fn: The function to map over the value\n /// - parameter or: The value to use if the optional is empty\n func map<T>(_ fn: (Wrapped) throws -> T, default: T) rethrows -> T {\n\treturn try map(fn) ?? `default`\n }\n\n /// Maps the output *or* returns the result of calling `else`\n /// - parameter fn: The function to map over the value\n /// - parameter else: The function to call if the optional is empty\n func map<T>(_ fn: (Wrapped) throws -> T, else: () throws -> T) rethrows -> T {\n\treturn try map(fn) ?? `else`()\n }\n}\n</pre>\n</div>\n\n<p>\nThe first one will allow you to <code>map</code> the contents of an optional to a new type <code>T</code>. If the optional is empty, you can define a <code>default</code> value that should be used instead:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let optional1: String? = \"appventure\"\nlet optional2: String? = nil\n\n// Without\nprint(optional1.map({ $0.count }) ?? 0)\nprint(optional2.map({ $0.count }) ?? 0)\n\n// With \nprint(optional1.map({ $0.count }, default: 0)) // prints 10\nprint(optional2.map({ $0.count }, default: 0)) // prints 0\n</pre>\n</div>\n\n<p>\nThe changes are minimal, but we're moving away from having to use the <code>??</code> operator and can instead express the operation more clearly with the <code>default</code> keyword.\n</p>\n\n<p>\nThe second variant is very similar. The main difference is that it accepts (again) a closure returning value <code>T</code> instead of value <code>T</code>. Here's a brief example:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let optional: String? = nil\nprint(optional.map({ $0.count }, else: { \"default\".count })\n</pre>\n</div>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-sec-3\" class=\"outline-2\">\n<h2 id=\"sec-3\"><span class=\"section-number-2\">3</span> Combining Optionals</h2>\n<div class=\"outline-text-2\" id=\"text-3\">\n<p>\nThis category contains four functions that allow you to define relations between multiple optionals.\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\" id=\"feature-image\">extension Optional {\n /// Tries to unwrap `self` and if that succeeds continues to unwrap the parameter `optional`\n /// and returns the result of that.\n func and<B>(_ optional: B?) -> B? {\n\tguard self != nil else { return nil }\n\treturn optional\n }\n\n /// Executes a closure with the unwrapped result of an optional.\n /// This allows chaining optionals together.\n func and<T>(then: (Wrapped) throws -> T?) rethrows -> T? {\n\tguard let unwrapped = self else { return nil }\n\treturn try then(unwrapped)\n }\n\n /// Zips the content of this optional with the content of another\n /// optional `other` only if both optionals are not empty\n func zip2<A>(with other: Optional<A>) -> (Wrapped, A)? {\n\tguard let first = self, let second = other else { return nil }\n\treturn (first, second)\n }\n\n /// Zips the content of this optional with the content of another\n /// optional `other` only if both optionals are not empty\n func zip3<A, B>(with other: Optional<A>, another: Optional<B>) -> (Wrapped, A, B)? {\n\tguard let first = self,\n\t let second = other,\n\t let third = another else { return nil }\n\treturn (first, second, third)\n }\n}\n</pre>\n</div>\n\n<p>\nThese 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.\n</p>\n</div>\n\n<div id=\"outline-container-sec-3-1\" class=\"outline-3\">\n<h3 id=\"sec-3-1\"><span class=\"section-number-3\">3.1</span> Dependencies</h3>\n<div class=\"outline-text-3\" id=\"text-3-1\">\n<p>\n<code>and<B>(_ optional)</code> is useful if the unpacking of an optional is only required as a invariant for\nunpacking another optional:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">// Compare\nif user != nil, let account = userAccount() ...\n\n// With\nif let account = user.and(userAccount()) ...\n</pre>\n</div>\n\n<p>\nIn the example above, we're not interested in the unwrapped contents of the <code>user</code> optional. We just need to make sure that there <b>is</b> a valid user before we call the <code>userAccount</code> function. While this relationship is kinda codified in the <code>user != nil</code> line, I personally feel that the <code>and</code> makes it more clear.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-3-2\" class=\"outline-3\">\n<h3 id=\"sec-3-2\"><span class=\"section-number-3\">3.2</span> Chaining</h3>\n<div class=\"outline-text-3\" id=\"text-3-2\">\n<p>\n<code>and<T>(then:)</code> is another very useful function. It allows to chain optionals together so that the output of unpacking optional <code>A</code> becomes the input of producing optional <code>B</code>. Lets start with a simple example:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol UserDatabase {\n func current() -> User?\n func spouse(of user: User) -> User?\n func father(of user: User) -> User?\n func childrenCount(of user: User) -> Int\n}\n\nlet database: UserDatabase = ...\n\n// Imagine we want to know the children of the following relationship:\n// Man -> Spouse -> Father -> Father -> Spouse -> children\n\n// Without\nlet childrenCount: Int\nif let user = database.current(), \n let father1 = database.father(user),\n let father2 = database.father(father1),\n let spouse = database.spouse(father2),\n let children = database.childrenCount(father2) {\n childrenCount = children\n} else {\n childrenCount = 0\n}\n\n// With\nlet children = database.current().and(then: { database.spouse($0) })\n .and(then: { database.father($0) })\n .and(then: { database.spouse($0) })\n .and(then: { database.childrenCount($0) })\n .or(0)\n</pre>\n</div>\n\n<p>\nThere're a lot of improvements when using the version with <code>and(then)</code>. 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 <code>or(0)</code> instead of a complicated <code>let childrenCount</code> is so much easier to read.\n</p>\n\n<p>\nFinally, 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?\n</p>\n\n<p>\nYeah, the <code>children</code> property should be created by calling <code>database.childrenCount(spouse)</code> but I wrote <code>database.childrenCount(father2)</code> instead. It is difficult to spot errors like that. The <code>and(then:)</code> example makes it much easier because it always relies on the same variable name <code>$0</code>.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-3-3\" class=\"outline-3\">\n<h3 id=\"sec-3-3\"><span class=\"section-number-3\">3.3</span> Zipping</h3>\n<div class=\"outline-text-3\" id=\"text-3-3\">\n<p>\nThis is another variation on an existing Swift concept. The <code>zip</code> method on optional will allow us to combine multiple optionals and unwrap them together or not at all. I've just provided implementations for <code>zip2</code> and <code>zip3</code> but nothing prevents you from going up to <code>zip22</code> (Well, maybe sanity and compiler speed).\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">// Lets start again with a normal Swift example\nfunc buildProduct() -> Product? {\n if let var1 = machine1.makeSomething(),\n let var2 = machine2.makeAnotherThing(),\n let var3 = machine3.createThing() {\n return finalMachine.produce(var1, var2, var3)\n } else {\n return nil\n }\n}\n\n// The alternative using our extensions\nfunc buildProduct() -> Product? {\n return machine1.makeSomething()\n .zip3(machine2.makeAnotherThing(), machine3.createThing())\n .map { finalMachine.produce($0.1, $0.2, $0.3) }\n}\n</pre>\n</div>\n\n<p>\nLess code, clearer code, more beautiful code. However, as a downside, this code is also more involved. The reader has to know and understand <code>zip</code> in order to easily grasp it. \n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-3-4\" class=\"outline-3\">\n<h3 id=\"sec-3-4\"><span class=\"section-number-3\">3.4</span> On</h3>\n<div class=\"outline-text-3\" id=\"text-3-4\">\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">extension Optional {\n /// Executes the closure `some` if and only if the optional has a value\n func on(some: () throws -> Void) rethrows {\n\tif self != nil { try some() }\n }\n\n /// Executes the closure `none` if and only if the optional has no value\n func on(none: () throws -> Void) rethrows {\n\tif self == nil { try none() }\n }\n}\n</pre>\n</div>\n\n<p>\nThese 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 <code>on(some:)</code> will only execute the closure <code>some</code> if the optional is not empty but the closure <code>some</code> will not get the unwrapped contents of the optional.\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">/// Logout if there is no user anymore\nself.user.on(none: { AppCoordinator.shared.logout() })\n\n/// self.user is not empty when we are connected to the network\nself.user.on(some: { AppCoordinator.shared.unlock() })\n</pre>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-sec-3-5\" class=\"outline-3\">\n<h3 id=\"sec-3-5\"><span class=\"section-number-3\">3.5</span> Various</h3>\n<div class=\"outline-text-3\" id=\"text-3-5\">\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">extension Optional {\n /// Returns the unwrapped value of the optional only if\n /// - The optional has a value\n /// - The value satisfies the predicate `predicate`\n func filter(_ predicate: (Wrapped) -> Bool) -> Wrapped? {\n\tguard let unwrapped = self,\n\t predicate(unwrapped) else { return nil }\n\treturn self\n }\n\n /// Returns the wrapped value or crashes with `fatalError(message)`\n func expect(_ message: String) -> Wrapped {\n\tguard let value = self else { fatalError(message) }\n\treturn value\n }\n}\n</pre>\n</div>\n</div>\n\n<div id=\"outline-container-sec-3-5-1\" class=\"outline-4\">\n<h4 id=\"sec-3-5-1\"><span class=\"section-number-4\">3.5.1</span> Filter</h4>\n<div class=\"outline-text-4\" id=\"text-3-5-1\">\n<p>\nThis 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:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">// Only affect old users with id < 1000\n// Normal Swift\nif let aUser = user, user.id < 1000 { aUser.upgradeToPremium() }\n\n// Using `filter`\nuser.filter({ $0.id < 1000 })?.upgradeToPremium()\n</pre>\n</div>\n\n<p>\nHere, <code>user.filter</code> feels like a much more natural implementation. Also, it only implements what already exists for Swift's collections.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-3-5-2\" class=\"outline-4\">\n<h4 id=\"sec-3-5-2\"><span class=\"section-number-4\">3.5.2</span> Expect</h4>\n<div class=\"outline-text-4\" id=\"text-3-5-2\">\n<p>\nThis 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.\n</p>\n\n<p>\nHowever, this is tricky when working with interface builder outlets. A common pattern that I observed can be seen in the following function:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">func updateLabel() {\n guard let label = valueLabel else {\n fatalError(\"valueLabel not connected in IB\")\n }\n label.text = state.title\n}\n</pre>\n</div>\n\n<p>\nThe alternative solution, obviously, would be to just to force unwrap the label, as that leads to a crash just like <code>fatalError</code>. Then, I'd have to insert <code>!</code> though, also it wouldn't give me a nice succinct description of what actually is wrong. The better alternative here is to use <code>expect</code> as implemented above:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">func updateLabel() {\n valueLabel.expect(\"valueLabel not connected in IB\").text = state.title\n}\n</pre>\n</div>\n</div>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-sec-4\" class=\"outline-2\">\n<h2 id=\"sec-4\"><span class=\"section-number-2\">4</span> Example</h2>\n<div class=\"outline-text-2\" id=\"text-4\">\n<p>\nSo now that we've seen a couple of (hopefully) useful <code>Optional</code> 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:\n</p>\n\n<p>\nYou'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:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol XMLImportNode {\n func firstChild(with tag: String) -> XMLImportNode?\n func children(with tag: String) -> [XMLImportNode]\n func attribute(with name: String) -> String?\n}\n\ntypealias DatabaseUser = String\ntypealias DatabaseSoftware = String\nprotocol Database {\n func user(for id: String) throws -> DatabaseUser\n func software(for id: String) throws -> DatabaseSoftware\n func insertSoftware(user: DatabaseUser, name: String, id: String, type: String, amount: Int) throws\n func updateSoftware(software: DatabaseSoftware, amount: Int) throws\n}\n</pre>\n</div>\n\n<p>\nA typical file looks like this (behold the almighty XML):\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-xml\"><<span style=\"font-weight: bold;\">users</span>>\n <<span style=\"font-weight: bold;\">user</span> <span style=\"font-weight: bold; font-style: italic;\">name</span>=<span style=\"font-style: italic;\">\"\"</span> <span style=\"font-weight: bold; font-style: italic;\">id</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">158</span><span style=\"font-style: italic;\">\"</span>>\n <<span style=\"font-weight: bold;\">software</span>>\n <<span style=\"font-weight: bold;\">package</span> <span style=\"font-weight: bold; font-style: italic;\">type</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">game</span><span style=\"font-style: italic;\">\"</span> <span style=\"font-weight: bold; font-style: italic;\">name</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">Maniac Mansion</span><span style=\"font-style: italic;\">\"</span> <span style=\"font-weight: bold; font-style: italic;\">id</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">4332</span><span style=\"font-style: italic;\">\"</span> <span style=\"font-weight: bold; font-style: italic;\">amount</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">30</span><span style=\"font-style: italic;\">\"</span> />\n <<span style=\"font-weight: bold;\">package</span> <span style=\"font-weight: bold; font-style: italic;\">type</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">game</span><span style=\"font-style: italic;\">\"</span> <span style=\"font-weight: bold; font-style: italic;\">name</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">Doom</span><span style=\"font-style: italic;\">\"</span> <span style=\"font-weight: bold; font-style: italic;\">id</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">1337</span><span style=\"font-style: italic;\">\"</span> <span style=\"font-weight: bold; font-style: italic;\">amount</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">50</span><span style=\"font-style: italic;\">\"</span> />\n <<span style=\"font-weight: bold;\">package</span> <span style=\"font-weight: bold; font-style: italic;\">type</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">game</span><span style=\"font-style: italic;\">\"</span> <span style=\"font-weight: bold; font-style: italic;\">name</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">Warcraft 2</span><span style=\"font-style: italic;\">\"</span> <span style=\"font-weight: bold; font-style: italic;\">id</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">1000</span><span style=\"font-style: italic;\">\"</span> <span style=\"font-weight: bold; font-style: italic;\">amount</span>=<span style=\"font-style: italic;\">\"</span><span style=\"font-style: italic;\">10</span><span style=\"font-style: italic;\">\"</span> />\n </<span style=\"font-weight: bold;\">software</span>>\n </<span style=\"font-weight: bold;\">user</span>>\n</<span style=\"font-weight: bold;\">users</span>>\n</pre>\n</div>\n\n<p>\nOur original Swift code to parse the XML looks like this:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">enum ParseError: Error {\n case msg(String)\n}\n\nfunc parseGamesFromXML(from root: XMLImportNode, into database: Database) throws {\n guard let users = root.firstChild(with: \"users\")?.children(with: \"user\") else {\n\tthrow ParseError.msg(\"No Users\")\n }\n for user in users {\n\tguard let software = user.firstChild(with: \"software\")?\n\t\t.children(with: \"package\"),\n\t let userId = user.attribute(with: \"id\"),\n\t let dbUser = try? database.user(for: userId)\n\t else { throw ParseError.msg(\"Invalid User\") }\n\tfor package in software {\n\t guard let type = package.attribute(with: \"type\"),\n\t type == \"game\",\n\t let name = package.attribute(with: \"name\"),\n\t let softwareId = package.attribute(with: \"id\"),\n\t let amountString = package.attribute(with: \"amount\")\n\t else { throw ParseError.msg(\"Invalid Package\") }\n\t if let existing = try? database.software(for: softwareId) {\n\t\ttry database.updateSoftware(software: existing, \n\t\t\t\t\t amount: Int(amountString) ?? 0)\n\t } else {\n\t\ttry database.insertSoftware(user: dbUser, name: name, \n\t\t\t\t\t id: softwareId, \n\t\t\t\t\t type: type, \n\t\t\t\t\t amount: Int(amountString) ?? 0)\n\t }\n\t}\n }\n}\n</pre>\n</div>\n\n<p>\nLets apply what we learned above:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">func parseGamesFromXML(from root: XMLImportNode, into database: Database) throws {\n for user in try root.firstChild(with: \"users\")\n\t\t .or(throw: ParseError.msg(\"No Users\")).children(with: \"user\") {\n\tlet dbUser = try user.attribute(with: \"id\")\n\t\t .and(then: { try? database.user(for: $0) })\n\t\t .or(throw: ParseError.msg(\"Invalid User\"))\n\tfor package in (user.firstChild(with: \"software\")?\n\t\t .children(with: \"package\")).or([]) {\n\t guard (package.attribute(with: \"type\")).filter({ $0 == \"game\" }).isSome\n\t\telse { continue }\n\t try package.attribute(with: \"name\")\n\t\t.zip3(with: package.attribute(with: \"id\"), \n\t\t another: package.attribute(with: \"amount\"))\n\t\t.map({ (tuple) -> Void in\n\t\t switch try? database.software(for: tuple.1) {\n\t\t case let e?: try database.updateSoftware(software: e, \n\t\t\t\t\t\t\t amount: Int(tuple.2).or(0))\n\t\t default: try database.insertSoftware(user: dbUser, name: tuple.0, \n\t\t\t\t\t\t\t id: tuple.1, type: \"game\", \n\t\t\t\t\t\t amount: Int(tuple.2).or(0))\n\t\t }\n\t\t}, or: { throw ParseError.msg(\"Invalid Package\") })\n\t}\n }\n}\n</pre>\n</div>\n\n<p>\nIf we look at this, then there're two things that immediately come to mind:\n</p>\n<ol class=\"org-ol\">\n<li>Less Code\n</li>\n<li>More Complicated Looking Code\n</li>\n</ol>\n\n<p>\nI deliberately went into overdrive when utilizing the various <code>Optional</code> 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 <code>Optional</code> extensions.\n</p>\n\n<p>\nThat's all for today, thanks for reading!\n</p>\n</div>\n</div>\n",
:keywords "swift protocol optional optionals extensions",
:title "Useful Optional Extensions",
:filename "2018-01-10-optional-extensions.org",
:id -737992091,
:url "/2018/01/10/optional-extensions/",
:javadate #inst "2018-01-09T23:00:00.000-00:00",
:keyword-keywords
(:swift :protocol :optional :optionals :extensions)}
{:keyword-tags (:swift :cocoa :ios),
:tags "swift cocoa ios",
:date "Sun, 10 Dec 2017",
:footnotes nil,
:meta
{:feature-image
"/img-content/2017-12-10-patterns-for-working-with-associated-types-feature-image.jpg",
:title "Patterns for Working With Associated Types",
:keyword-tags (:swift :cocoa :ios),
:tags "swift cocoa ios",
:keyword-keywords
(:swift
:protocol
:protocols
:associated
:associatedtype
:typealias
:pattern
:pat),
:keywords
"swift protocol protocols associated associatedtype typealias pattern pat",
:summary
"Understand how to model your way around some of the issues that arise when introducing associated typed protocols into your codebase",
:description
"Understand how to model your way around some of the issues that arise when introducing associated typed protocols into your codebase",
:options "toc:nil"},
:content
"<!-- #+feature-image: /img-content/2017-12-10-patterns-for-working-with-associated-types-feature-image.jpg -->\n\n\n<div id=\"outline-container-sec-1\" class=\"outline-2\">\n<h2 id=\"sec-1\"><span class=\"section-number-2\">1</span> Useful Patterns for Working Your Way Around Associated Types</h2>\n<div class=\"outline-text-2\" id=\"text-1\">\n<p>\nThis blog post is based <a href=\"https://www.youtube.com/watch?v=P_ifSjia9mE\">on a talk I gave</a> at <a href=\"https://www.appbuilders.ch/\">AppBuilders 2016</a> explaining protocols with associated types offering tips for using them. \n</p>\n\n<p>\nSwift is a powerful language with a very powerful type system. Among the features that define said type system are <code>associated types</code>. They can be defined on a <code>protocol</code> to allow implementors of the <code>protocol</code> to specialize certain types in a generic way:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol Example {\n associatedtype Value\n var value: Value { get }\n}\n</pre>\n</div>\n\n<p>\nIn the snippet above, any type that implements the <code>Example</code> protocol has to define the <code>Value</code> type. Protocols with <code>associated types</code> can be understood as <b>unfinished types</b>. 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 <code>associated type</code>, using it suddenly becomes much more complicated.\n</p>\n\n<p>\nThe example below shows an example of <b><b>finishing</b></b> a type. By explicitly telling the compiler that the <code>Value</code> type is <code>Int</code> it is now able to understand <code>ImplementExample</code> fully.\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">struct ImplementExample: Example {\n typealias Value = Int\n}\n</pre>\n</div>\n\n<p>\nAssociated types are useful for a certain kind of problems where subclassing and composition does allow you to <a href=\"https://www.appbuilders.ch/\">build the right kind of abstractions</a>. 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.\n</p>\n</div>\n</div>\n\n\n<div id=\"outline-container-sec-2\" class=\"outline-2\">\n<h2 id=\"sec-2\"><span class=\"section-number-2\">2</span> Associated Types Trouble</h2>\n<div class=\"outline-text-2\" id=\"text-2\">\n<p>\nThe classic example of <code>associated types</code> trouble certainly is the following Swift error message:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-bash\">protocol 'Bookmarkable' can only be used as a generic constraint because it has Self \nor associated type requirements\nvar bookmarks: [Bookmarkable]\n</pre>\n</div>\n\n<p>\nThis happens once your type conforms to a protocol which conforms to <code>Equatable</code>:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol Bookmarkable: Equatable {\n}\n\nstruct User {\n var bookmarks: [Bookmarkable]\n}\n</pre>\n</div>\n\n<p>\nHere, the problem is that <code>Equatable</code> contains a method <code>==</code> which has two paramters of type <code>Self</code>. Protocol Methods with <code>Self</code> parameters automatically opt in to <code>associated types</code>.\n</p>\n\n<p>\nIn this article, we will be investigating several patterns that allow you to work your way around the <code>associated type</code> requirement or that show how such a type can be handled.\n</p>\n</div>\n</div>\n\n\n<div id=\"outline-container-sec-3\" class=\"outline-2\">\n<h2 id=\"sec-3\"><span class=\"section-number-2\">3</span> Working Around Associated Types</h2>\n</div>\n\n\n<div id=\"outline-container-sec-4\" class=\"outline-2\">\n<h2 id=\"sec-4\"><span class=\"section-number-2\">4</span> Make Your Types Equatable</h2>\n<div class=\"outline-text-2\" id=\"text-4\">\n<p>\nThe first solution for the archetypical problem is also a really simple one. Instead of enforcing <code>Equatable</code> on your custom <code>protocol</code>, you can simply require your full fledged, final, types to conform to the <code>Equatable</code> protocol instead of your custom protocol. Consider the previously defined <code>Bookmarkable</code> protocol:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol Bookmarkable {\n}\n\nstruct Bookmark: Bookmarkable, Equatable {\n var identifier: Int\n}\n\nfunc ==(lhs: Bookmark, rhs: Bookmark) -> Bool {\n return lhs.identifier == rhs.identifier\n}\n\nvar myBookmarks: [Bookmark] = []\n</pre>\n</div>\n\n<p>\nIn the example above, the <code>Equatable</code> requirement actually stems from the <code>Bookmark</code> type conforming to the <code>Equatable</code> protocol, not the <code>Bookmarkable</code> protocol itself. The actual <code>Equatable</code> information, however, lies in the new <code>identifier</code> property, which has been added to the <code>Bookmark</code> <code>struct</code>. As you can easily see, this also requires you to make the <code>myBookmarks</code> array require only elements of type <code>Bookmark</code>. 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 <code>property</code> which we introduced in this example.\n</p>\n</div>\n\n\n<div id=\"outline-container-sec-4-1\" class=\"outline-3\">\n<h3 id=\"sec-4-1\"><span class=\"section-number-3\">4.1</span> Equatable Properties</h3>\n<div class=\"outline-text-3\" id=\"text-4-1\">\n<p>\nHere, the idea is that we take one of the types that already implement <code>Equatable</code> in a proper way (i.e. <code>Int</code>, <code>String</code>, …) and add a new <code>property</code> requirement to our <code>Bookmarkable</code> protocol. Then, we can use this <code>property</code> to add <code>Equatable</code> support without actually implementing <code>Equatable</code>:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol Bookmarkable {\n var identifier: Int { get }\n}\n\nstruct Bookmark: Bookmarkable {\n var identifier: Int\n}\n\nvar myBookmarks: [Bookmarkable] = []\n</pre>\n</div>\n\n<p>\nThe main change, compared to the code above, is that the <code>var identifier</code> moved to the <code>Bookmarkable</code> protocol and that we removed the <code>func ==</code>.\n</p>\n\n<p>\nWhile this works better, it still has a major deficit. Since <code>Bookmarkable</code> does not directly comply with <code>Equatable</code>, you will not gain the standard library's methods that specifically deal with <code>Equatable</code> types. So instead of being able to call <code>Array.contains</code> like this:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let ourBookmark = Bookmark(identifier: 0)\nlet result = myBookmarks.contains(ourBookmark)\n</pre>\n</div>\n\n<p>\nYou will have to use the more verbose closure-based version:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let ourBookmark = Bookmark(identifier: 0)\n\nlet result = myBookmarks.contains { (bookmark) -> Bool in\n return bookmark.identifier == ourBookmark.identifier\n}\n</pre>\n</div>\n</div>\n</div>\n</div>\n\n\n<div id=\"outline-container-sec-5\" class=\"outline-2\">\n<h2 id=\"sec-5\"><span class=\"section-number-2\">5</span> Associated Types and Self</h2>\n<div class=\"outline-text-2\" id=\"text-5\">\n<p>\nAnother vector which can introduce <code>associated types</code> into your codebase is the usage of <code>Self</code>:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol Example {\n /// Indirect Associated Type\n var builder: Self { get }\n /// Indirect Associated Type\n func makeSomething(with example: Self)\n}\nvar myExamples: [Example] = []\n</pre>\n</div>\n\n<p>\nAs you can see in the example above, using <code>Self</code> as a method parameter or using <code>Self</code> as a property type automatically introduces an <code>associated type</code> (like we saw with <code>Equatable</code>, earlier).\n</p>\n\n<p>\nThe most helpful note here is that once you use a <code>method</code> instead of a <code>property</code> in order to return something of type <code>Self</code> you will not opt in to an <code>associated type</code>:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol Example {\n /// No Indirect Associated Type\n func builder() -> Self\n}\nvar myExamples: [Example] = []\n</pre>\n</div>\n\n<p>\nThis example works fine. No <code>indirect associated</code> type is introduced.\n</p>\n</div>\n</div>\n\n\n<div id=\"outline-container-sec-6\" class=\"outline-2\">\n<h2 id=\"sec-6\"><span class=\"section-number-2\">6</span> Method-Only Types</h2>\n<div class=\"outline-text-2\" id=\"text-6\">\n<p>\nIf your <code>associated type</code> requirement doesn't come from <code>Equatable</code> conformance but instead from your own use, you can double-check if you actually need these associated types.\n</p>\n\n<p>\nTake this example of a validator type:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol Validator {\n associatedtype I\n func validate(_ input: I) -> Bool\n}\n</pre>\n</div>\n\n<p>\nAs the <code>associated type</code> is only used in one method, you can alternatively just make it a <code>generic</code> method and thus save yourself from introducing unnecessary unfinished types:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol Validator {\n func validate<I>(_ input: I) -> Bool\n}\n</pre>\n</div>\n</div>\n</div>\n\n\n<div id=\"outline-container-sec-7\" class=\"outline-2\">\n<h2 id=\"sec-7\"><span class=\"section-number-2\">7</span> Hiding Behind Protocols</h2>\n<div class=\"outline-text-2\" id=\"text-7\">\n<p>\nThis is an especially useful and flexible pattern. It can be used in many situations where you want to use protocols with <code>associated types</code> 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 <code>associated types</code>, the other does not. Your types conform to both protocols. This means that you can use the <b>normal</b> protocol as a type for all situations. If you, then, need to use the parts of the type that only affect the <code>associated type</code>, you can do so by means of a runtime cast.\n</p>\n\n<p>\nBegin by defining an <code>associated</code> Protocol <code>ExampleAssociatedProtocol</code> that is shadowed by a <code>normal</code> Protocol <code>ExampleProtocol</code>.\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\" id=\"feature-image\">/// The `Normal` Protocol\nprotocol ExampleProtocol {\n var anyValue: Any { get }\n}\n\n/// The Protocol with an associated type\nprotocol ExampleAssociatedProtocol: ExampleProtocol {\n associatedtype Value\n\n /// Retrieving the actual associated type\n var value: Value { get }\n}\n\n/// Conform to the `ExampleProtocol`\nextension ExampleAssociatedProtocol {\n var anyValue: Any {\n return value\n }\n}\n</pre>\n</div>\n\n<p>\nNow, you can use the <code>ExampleProtocol</code> as a normal type throughout your app in all situations where a protocol with an <code>associated type</code> would otherwise fail:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">struct World {\n var examples: [ExampleProtocol]\n\n let example: ExampleProtocol\n\n func generate() -> ExampleProtocol { \n return example\n }\n}\n</pre>\n</div>\n\n<p>\nHowever, if you need to access the property that is specific to the <code>ExampleAssociatedProtocol</code> (<code>value</code>) then you can do so through at runtime.\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">/// Custom type implementing `ExampleAssociatedProtocol`\nstruct IntExample: ExampleAssociatedProtocol {\n var value: Int\n}\n\n/// Custom type implementing `ExampleAssociatedProtocol`\nstruct StringExample: ExampleAssociatedProtocol {\n var value: String\n}\n\n/// Shadowing via `ExampleProtocol`\nlet myExamples: [ExampleProtocol] = \n [StringExample(value: \"A\"), IntExample(value: 10)]\n\n/// Runtime Casting\nfor aNormalExample in myExamples {\n if let anAssociatedExample = aNormalExample as? IntExample {\n print(anAssociatedExample.value)\n }\n if let anAssociatedExample = aNormalExample as? StringExample {\n print(anAssociatedExample.value)\n }\n}\n</pre>\n</div>\n\n<p>\nThis will print \"A10\" as both types (<code>IntExample</code> and <code>StringExample</code>) are being identified at runtime via a cast from <code>ExampleProtocol</code>.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-8\" class=\"outline-2\">\n<h2 id=\"sec-8\"><span class=\"section-number-2\">8</span> Type Erasure</h2>\n<div class=\"outline-text-2\" id=\"text-8\">\n</div><div id=\"outline-container-sec-8-1\" class=\"outline-3\">\n<h3 id=\"sec-8-1\"><span class=\"section-number-3\">8.1</span> The Problem</h3>\n<div class=\"outline-text-3\" id=\"text-8-1\">\n<p>\nQuite often, when Swift's associated types are dicussed, <code>type erasure</code> is mentioned as another solution to the problem of handling the issues that <code>associated types</code> bring along.\n</p>\n\n<p>\nType Erasure in the context of <code>associated types</code> 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 <code>endianness</code> of the architecture. Lets model these computers in Swift:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol CPU {\n var littleEndian: Bool { get }\n}\n\nstruct PowerPC: CPU {\n let littleEndian = false\n}\n\nstruct X86: CPU {\n let littleEndian = true\n}\n</pre>\n</div>\n\n<p>\nNext 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 <code>associated type</code>, so that the actual type can define the CPU:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">protocol Computer {\n associatedtype ProcessorType: CPU\n var processor: ProcessorType { get }\n var processorCount: Int { get }\n}\n</pre>\n</div>\n\n<p>\nBased on this, we can now define a couple of systems:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">struct PowerMacG5: Computer {\n let processor = PowerPC()\n let processorCount = 2\n}\n\nstruct Xbox360: Computer {\n let processor = PowerPC()\n let processorCount = 1\n}\n\nstruct MacPro: Computer {\n let processor = X86()\n let processorCount = 1\n}\n</pre>\n</div>\n\n<p>\nNow that we have all this, we'd like to perform a computation on all <b>PowerPC</b> based computers. I.e. something like:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let powerComputers = [PowerMacG5(), Xbox360()]\n</pre>\n</div>\n\n<p>\nHowever, what would be the type of this? We can't use the <code>Computer</code> protocol, as it contains <code>associated types</code>. However, the <code>associated types</code> for the PowerMacG5 <b>and</b> the Xbox360 <b>are</b> 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 <b>PowerMacG5</b> and <b>Xbox360</b> are not the correct types for the array:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">// None of those work\nlet powerComputers: [PowerMacG5] = [PowerMacG5(), Xbox360]\nlet powerComputers: [Xbox360] = [PowerMacG5(), Xbox360]\nlet powerComputers: [Computer] = [PowerMacG5(), Xbox360]\n</pre>\n</div>\n\n<p>\nType 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:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let powerComputers: [AnyComputer<PowerPC>] = [AnyComputer(PowerMacG5()), AnyComputer(Xbox360())]\n</pre>\n</div>\n\n<p>\nNow we would have our <b>shared</b> type, in this case it is <code>AnyComputer<CPU></code>. Where does this mystic <code>AnyComputer</code> 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. \n</p>\n</div>\n</div>\n\n\n<div id=\"outline-container-sec-8-2\" class=\"outline-3\">\n<h3 id=\"sec-8-2\"><span class=\"section-number-3\">8.2</span> An Abstract Class</h3>\n<div class=\"outline-text-3\" id=\"text-8-2\">\n<p>\nIn essense, what we're going to build, is a generic wrapper (or box) that hosts a type conforming to a <code>protocol</code> with an <code>associated type</code>. It does so by implementing the requirements of the <code>protocol</code> and forwarding all invocations to the boxed type.\n</p>\n\n<p>\nThe first new type we need for that is a base <code>class</code> that acts as a abstract class:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">class AnyComputerBase<Processor: CPU>: Computer {\n var processor: Processor {\n\tfatalError()\n }\n var processorCount: Int {\n\tfatalError()\n }\n}\n</pre>\n</div>\n\n<p>\nThis <code>class</code> 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 <code>fileprivate init</code> to this <code>class</code>. However as that requires subclasses to be in the same file as this superclass, we can also just make the whole <code>class</code> <code>private</code> with an even better result. Now, other parts of the code won't even know about the existence of <code>AnyComputerBase</code> or even <code>initialize</code> it:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">private class AnyComputerBase<Processor: CPU>: Computer {\n...\n}\n</pre>\n</div>\n\n<p>\nWhy do we even need this, and what does it do? As you can see, it just implements the <code>Computer</code> <code>protocol</code> by implementing the requirements and doing nothing in there. The more important part is that it moves the <code>associated type</code> from the protocol into a generic type for the <code>class</code>: <code>AnyComputerBase<Processor: CPU></code>.\n</p>\n\n<p>\nSwift automatically figures out that <code>Processor</code> is the <code>typealias</code> for <code>Computer.ProcessorType</code>. However, when in doubt you can also add an extra typealias:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">class AnyComputerBase<Processor: CPU>: Computer {\n typealias ProcessorType = Processor\n ...\n}\n</pre>\n</div>\n</div>\n</div>\n\n\n<div id=\"outline-container-sec-8-3\" class=\"outline-3\">\n<h3 id=\"sec-8-3\"><span class=\"section-number-3\">8.3</span> A Box Type</h3>\n<div class=\"outline-text-3\" id=\"text-8-3\">\n<p>\nThe 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 <code>private</code> 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:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">private class AnyComputerBox<ConcreteComputer: Computer>: \n\tAnyComputerBase<ConcreteComputer.ProcessorType> \n{\n private let internalComputer: ConcreteComputer\n override var processor: ConcreteComputer.ProcessorType {\n\treturn internalComputer.processor\n }\n override var processorCount: Int {\n\treturn internalComputer.processorCount\n }\n init(_ computer: ConcreteComputer) {\n\tinternalComputer = computer\n }\n}\n</pre>\n</div>\n\n<p>\nThe most important concept here can be found in the very first line:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">private class AnyComputerBox<ConcreteComputer: Computer>: \n\tAnyComputerBase<ConcreteComputer.ProcessorType>\n</pre>\n</div>\n\n<p>\nHere, we define a new type <code>AnyComputerBox</code> which is generic over <b>any</b> computer (<code>ConcreteComputer</code>). This new type, then, is a subclass of our earlier abstract class <code>AnyComputerBase</code>. Remember that <code>AnyComputerBase</code> made the original <code>ProcessorType</code> of the <code>Computer</code> protocol generic by adding it as a generic parameter <code>CPU</code>. Now, our new box has a <b>different</b> generic type (<code>Computer</code>) and provides only its <code>associated type</code> <b>ProcessorType</b> to the abstract superclass. In a simpler explanation, this is what happens (in a mock language):\n</p>\n\n<ol class=\"org-ol\">\n<li><code>Computer<CPU></code>\n</li>\n<li><code>AnyComputerBase<Processor: CPU>: Computer<CPU> where Computer.CPU = Processor</code>\n</li>\n<li><code>AnyComputerBox<ConcreteComputer: Computer>: AnyComputerBase<ConcreteComputer.ProcessorType></code>\n</li>\n</ol>\n\n<p>\nSo the box (<code>AnyComputerBox</code>) subclasses the abstract class and forwards in the <code>Processor</code> type via its own generic <code>Computer</code> type which also has a <code>ProcessorType</code>.\n</p>\n\n<p>\nWhy do we do this? It makes the box generic over any computer so that <b>any</b> computer can be boxed into it.\n</p>\n\n<p>\nThe rest of the <code>class</code> is simple. There's an <code>internal</code> computer <code>internalComputer</code> which is the actual type conforming to the <code>Computer</code> <code>protocol</code>. We're also overriding the two classes that are required by the protocol and forwarding the implementations of the <code>internalComputer</code>. Finally we have an initializer with a new <code>ConcreteComputer</code> (i.e. the <code>Computer</code> protocol).\n</p>\n</div>\n</div>\n\n\n<div id=\"outline-container-sec-8-4\" class=\"outline-3\">\n<h3 id=\"sec-8-4\"><span class=\"section-number-3\">8.4</span> Putting it all together</h3>\n<div class=\"outline-text-3\" id=\"text-8-4\">\n<p>\nIn 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:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">final class AnyComputer<Processor: CPU>: Computer {\n private let box: AnyComputerBase<Processor>\n var processor: Processor {\n\treturn box.processor\n }\n var processorCount: Int {\n\treturn box.processorCount\n }\n init<Concrete: Computer>(_ computer: Concrete) \n\twhere Concrete.ProcessorType == Processor {\n box = AnyComputerBox(computer)\n }\n}\n</pre>\n</div>\n\n<p>\nThis <code>AnyComputer</code> conforms to the <code>Computer</code> protocol and is generic over the <code>CPU</code> type that the protocol requires. Once again, we implement the protocol requirements (<code>processor</code>, and <code>processorCount</code>) and forward to a boxed type. This time we're forwarding to <code>private let box: AnyComputerBase<Processor></code>. This <code>box</code> is set in the initializer where most of the magic happens:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">init<Concrete: Computer>(_ computer: Concrete) \n where Concrete.ProcessorType == Processor {\n box = AnyComputerBox(computer)\n}\n</pre>\n</div>\n\n<p>\nThe problem with protocols with <code>associated types</code> is that you can't use them as property types. Here, <code>init</code> requires any type conforming to the <code>Computer</code> protocol. This is done by having a method-generic type <code>Concrete</code> that requires <code>Computer</code> conformance. Even more, we also add a constraint that makes sure that the generic <code>Processor</code> type of the new <code>AnyComputer</code> class is the same type as the <code>associated type</code> of the <code>Concrete</code> <code>Computer</code> type. \n</p>\n\n<p>\nAnd now comes the kicker: Since we cannot set a property as being of type <code>Computer</code> we, instead, have a property that is of <code>AnyComputerBase</code> with a generic type for the <code>Processor</code>. As our <code>AnyComputerBox</code> type is a subclass of <code>AnyComputerBase</code> we can literally put <b>any</b> box (that is a subclass of <code>AnyComputerBase</code> into this property. In this case, we're creating a new box with the <code>Concrete</code> <code>Computer</code>.\n</p>\n\n<p>\nThen we return the implementations of the contents of the box (i.e. the actual <code>Concrete</code> <code>Computer</code>) in our <code>Computer</code> implementations:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">var processorCount: Int {\n return box.processorCount\n}\n</pre>\n</div>\n</div>\n</div>\n\n\n<div id=\"outline-container-sec-8-5\" class=\"outline-3\">\n<h3 id=\"sec-8-5\"><span class=\"section-number-3\">8.5</span> Using It</h3>\n<div class=\"outline-text-3\" id=\"text-8-5\">\n<p>\nWith all this machinery in place, we can finally use this in order to have different types (which share an associated type) in one container:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let powerComputers: [AnyComputer<PowerPC>] = \n [AnyComputer(PowerMacG5()), AnyComputer(Xbox360())]\n</pre>\n</div>\n</div>\n</div>\n</div>\n\n\n<div id=\"outline-container-sec-9\" class=\"outline-2\">\n<h2 id=\"sec-9\"><span class=\"section-number-2\">9</span> Conclusion</h2>\n<div class=\"outline-text-2\" id=\"text-9\">\n<p>\n<code>Associated types</code> are a powerful concept however they come with a fair share of difficulties. Most notably, as soon as you introduce an <code>associated type</code> 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 <code>associated type</code> problems in your codebase. Each of these patterns has downsides though. In general, if you intend to use <code>associated types</code> in a <code>protocol</code>, one of the best solutions is to try to only use the types that implement this <code>protocol</code> instead of the <code>protocol</code> itself. Because then you don't even need those patterns.\n</p>\n</div>\n</div>\n",
:keywords
"swift protocol protocols associated associatedtype typealias pattern pat",
:title "Patterns for Working With Associated Types",
:filename
"2017-12-10-patterns-for-working-with-associated-types.org",
:id 3390524,
:url "/2017/12/10/patterns-for-working-with-associated-types/",
:javadate #inst "2017-12-09T23:00:00.000-00:00",
:keyword-keywords
(:swift
:protocol
:protocols
:associated
:associatedtype
:typealias
:pattern
:pat)}
{:keyword-tags (:swift :cocoa :ios),
:tags "swift cocoa ios",
:date "Sun, 8 Oct 2017",
:footnotes nil,
:meta
{:title "Taming SourceKitService for Less Xcode Memory Consumption",
:keyword-tags (:swift :cocoa :ios),
:tags "swift cocoa ios",
:keyword-keywords (:xcode :sourcekit :swift :SourceKitService),
:keywords "xcode sourcekit swift SourceKitService",
:summary
"Taming SourceKitService for less Xcode memory consumption",
:description
"Taming SourceKitService for less Xcode memory consumption",
:options "toc:nil"},
:content
"\n<div id=\"outline-container-sec-1\" class=\"outline-2\">\n<h2 id=\"sec-1\"><span class=\"section-number-2\">1</span> Update [10/15/2017]</h2>\n<div class=\"outline-text-2\" id=\"text-1\">\n<p>\n<a href=\"<a href=\"https://t.co/aJc8ZZSm9c\">https://t.co/aJc8ZZSm9c</a>\">It seems that Xcode 9.1 beta 2 fixes this issue.</a>\n</p>\n\n<p>\nIn my preliminary testing, everything worked fine. This feels really good.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-sec-2\" class=\"outline-2\">\n<h2 id=\"sec-2\"><span class=\"section-number-2\">2</span> Original Article</h2>\n<div class=\"outline-text-2\" id=\"text-2\">\n<p>\nThere were recently two popular Swift posts on Hacker News<sup><a id=\"fnr.1\" name=\"fnr.1\" class=\"footref\" href=\"#fn.1\">1</a></sup> <sup>, </sup><sup><a id=\"fnr.2\" name=\"fnr.2\" class=\"footref\" href=\"#fn.2\">2</a></sup>, 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 <code>SourceKitService</code> 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.\n</p>\n\n<p>\nOftentimes memory issues like these can be solved by reviewing your sourcecode with the same tools you also use to reduce your compile times. See:\n</p>\n\n<ul class=\"org-ul\">\n<li><a href=\"https://www.jessesquires.com/blog/measuring-compile-times-xcode9/\">https://www.jessesquires.com/blog/measuring-compile-times-xcode9/</a>\n</li>\n<li><a href=\"https://www.swiftbysundell.com/posts/improving-swift-compile-times\">https://www.swiftbysundell.com/posts/improving-swift-compile-times</a>\n</li>\n</ul>\n\n<p>\nHowever, for some, complex, codebases this may not be enough. I've employed an <b>awful</b> 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 <code>SourceKitService</code> every <code>n</code> seconds and if it goes beyond <code>x</code> megabytes of memory (by default <b>5.000</b>) 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 <code>SourceKitService</code> will probably (hopefully!) not need this anymore. Meanwhile, this might be of help to others:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-bash\">#!/bin/bash\n\n# Amount of seconds to wait between measures\nn=1\n# Limit memory consumption to this many megabytes before killing the process\nx=5000\n\nname=\"SourceKitService\"\nwhile true; do \n fields=`ps aux -m | grep -v grep | grep -i $name | tr -s ' '`\n mem=`echo $fields | cut -d ' ' -s -f 6| awk '{$1=$1/1024; print $1;}' | cut -d '.' -f 1`\n pid=`echo $fields | cut -d ' ' -s -f 2`\n if [ -z \"$mem\" ]; then\n echo \"$name not running\"\n sleep 15\n continue\n fi\n if [ \"$mem\" -gt $x ]; then\n echo \"Killing $name pid $pid with mem $mem\"\n kill -9 $pid\n sleep 5\n fi\n sleep $n\ndone\n</pre>\n</div>\n\n<p>\nTo use this just paste that code into a file (say <code>sourcekill.sh</code>) and do:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-bash\">chmod +x ./sourcekill.sh\n./sourcekill.sh\n</pre>\n</div>\n\n<p>\nIf you want to kill it, just hit <code>CTRL=C</code>.\n</p>\n</div>\n</div>\n<div id=\"footnotes\">\n<h2 class=\"footnotes\">Footnotes: </h2>\n<div id=\"text-footnotes\">\n\n<div class=\"footdef\"><sup><a id=\"fn.1\" name=\"fn.1\" class=\"footnum\" href=\"#fnr.1\">1</a></sup> <p>Why many developers still prefer Objective-C <a href=\"https://news.ycombinator.com/item?id=15421073\">https://news.ycombinator.com/item?id=15421073</a></p></div>\n\n<div class=\"footdef\"><sup><a id=\"fn.2\" name=\"fn.2\" class=\"footnum\" href=\"#fnr.2\">2</a></sup> <p>Dictionary and Set Improvements in Swift 4.0 <a href=\"https://news.ycombinator.com/item?id=15403882\">https://news.ycombinator.com/item?id=15403882</a></p></div>\n\n\n</div>\n</div>",
:keywords "xcode sourcekit swift SourceKitService",
:title "Taming SourceKitService for Less Xcode Memory Consumption",
:filename "2017-10-08-taming-sourcekitd.org",
:id -1331039819,
:url "/2017/10/08/taming-sourcekitd/",
:javadate #inst "2017-10-07T22:00:00.000-00:00",
:keyword-keywords (:xcode :sourcekit :swift :SourceKitService)}
{:keyword-tags (:swift :cocoa :ios),
:tags "swift cocoa ios",
:date "Sat, 30 Sep 2017",
:footnotes nil,
:meta
{:title "Value Types for Simple Difference Detection",
:keyword-tags (:swift :cocoa :ios),
:tags "swift cocoa ios",
:keyword-keywords
(:swift
:value
:types
:uitableview
:uicollectionview
:valuetypes
:struct
:class
:equatable
:tuple),
:keywords
"swift value types uitableview uicollectionview valuetypes struct class equatable tuple",
:summary
"Utilize value types to quickly determine a differences between two sets of data",
:description
"Utilize value types to quickly determine a differences between two sets of data",
:options "toc:nil"},
:content
"<p>\nFollowing sage advice I received from <a href=\"https://www.swiftbysundell.com/\">John Sundell</a> half a year ago (I am a slow learner) I will try to write about smaller pieces instead of focusing on longform content. This should make it easier to update appventure more often. Thanks John!.\n</p>\n\n<p>\nToday, I'll write about value types: Value types are a very useful addition to Swift. Objective-C did offer C <code>struct</code> types and (obviously) classical value types such as numbers, but Swift goes way beyond that by allowing us to also define more complex structures such as <code>Array</code>, <code>Set</code>, or <code>Dictionary</code> as value types. One of the best properties of value types is that they can easily be compared given that they're values:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let one = [1, 2, 3]\nlet two = [1, 2, 3]\nprint(one == two) // returns true\n</pre>\n</div>\n\n<p>\nThis way of easily comparing arrays is something we can use to implement a simple difference detection algorithm without using more heavy-weight solutions. Imagine you have a simple app that downloads a list of entries from a server and displays them in a table view. Once a minute you download a new list and reload the table view. This is not a particularly nice solution as you're reloading the table view even when there're no changes. If your data is defined as a <code>struct</code> and you implement the <code>Equatable</code> protocol, then you can simply use the equality operator to see if the table view needs to be reloaded:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">struct Data: Equatable {\n let username: String\n let userid: Int\n static func ==(lhs: Data, rhs: Data) -> Bool {\n return lhs.username == rhs.username && lhs.userid == rhs.userid\n }\n}\nlet oldData: [Data] = currentData()\nlet newData: [Data] = retrieveNewData()\nguard oldData != newData else {\n return\n}\nupdateData(with: newData)\n</pre>\n</div>\n\n<p>\nHowever, it may be that your data is modelled using <code>struct</code> types, but that they're very complex and change often. So you've never implemented <code>Equatable</code>. Then you have three different options:\n</p>\n\n<ol class=\"org-ol\">\n<li>Wait for Swift 4.1 which will <a href=\"https://github.com/apple/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md\">hopefully merge a PR which will auto-generate</a> <code>Equatable</code> for <code>struct</code> types if all properties of a <code>struct</code> also conform to <code>Equatable</code>.\n</li>\n<li>Use Krzysztof Zabłocki's <a href=\"https://github.com/krzysztofzablocki/Sourcery\">Sourcery</a> which is a meta programming framework that allows you to auto generate things like <code>Equatable</code> conformance for your types (and much more).\n</li>\n<li>This I will explain in more detail as it is also a pattern that you can use if your data is modelled using <code>class</code> types.\n</li>\n</ol>\n\n<p>\nThe idea here is to store just the absolutely necessary information in a seperate difference detection cache. Imagine the following data model:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">final class Story {\n let story_id: Int\n let views: Int\n let last_updated: TimeInterval\n let description: String\n}\n</pre>\n</div>\n\n<p>\nIn this example, a Story will never change its id and description. In order to create a simple cache, we can now just use the information we absolutely need to determine a change and store them in tuples. Tuples with up to 6 elements will automatically generate <code>Equatable</code> conformance:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let a = (1, 2, 3)\nlet b = (1, 2, 3)\nprint(a == b)\n</pre>\n</div>\n\n<p>\nWith this in mind, we can generate our tuples:\n</p>\n\n<div class=\"org-src-container\">\n\n<pre class=\"src src-swift\">let newInformation: [(Int, Int, TimeInterval)] = \n stories.map({ ($0.story_id, $0.views, $0.last_updated) })\n\nguard newInformation != oldInformation else { return }\n</pre>\n</div>\n\n<p>\nThis is a simple solution that leverages value types to give us an easy solution for comparing sets of data. However, if you also need to determine insertions, deletions and moves then you can still do so with value types, but you need a proper diff algorithm such as <a href=\"https://github.com/jflinter/Dwifft\">Dwifft</a>.\n</p>\n\n<p>\nNevertheless, for many simpler use cases it is good to remember that we can easily build a comparison cache of tuples or structs to determine general changes to data.\n</p>\n",
:keywords
"swift value types uitableview uicollectionview valuetypes struct class equatable tuple",
:title "Value Types for Simple Difference Detection",
:filename
"2017-09-30-value-types-for-simple-difference-detection.org",
:id 774048296,
:url "/2017/09/30/value-types-for-simple-difference-detection/",
:javadate #inst "2017-09-29T22:00:00.000-00:00",
:keyword-keywords
(:swift
:value
:types
:uitableview
:uicollectionview
:valuetypes
:struct
:class
:equatable
:tuple)})