# August 20, 2014

## Swift, Extensions, Protocols, and Operator overloading

I’m working on a Swift matrix manipulation library. Since I want that library to be flexible enough to be used outside of my planned use, a simulation engine, it needs to be able to handle complex numbers. Swift doesn’t have representations for imaginary or complex numbers so I created one. You can get the source for the entire library at my gitHub repo. I call the library SwiftlyComplex. Regardless of why I created the library, there are some Swift programming concepts the library illustrates.

I wanted my representation of complex numbers to be able to have Int and Double type parts but not String or other invalid types. Swift’s implementation of Int and Double have no common base class so I could have done something silly with Swifts **Any** type and do a bunch of run-time checking or I could have overloaded all my functions to handle all possible combinations of **Int** and **Double**. Both of these are bad ideas. For example, if the complex number’s init function had two parameters, one of the real component and one for the imaginary, using the overloading idea I would need to create four init methods that do essentially the same thing, initialize the complex number’s properties. The overloading approach would also make it difficult to declare the complex number’s property types as well. Not a good approach.

So what I did instead was create a BaseNumeric protocol.

protocol BaseNumeric { func asDouble() -> Double func asInt() -> Int } extension Int:BaseNumeric { func asDouble() -> Double{ return Double(self) } func asInt() -> Int{ return self } } extension Double:BaseNumeric { func asDouble() -> Double{ return self } func asInt() -> Int{ return Int(self) } }

As you can see, I used this protocol to extend both **Int** and **Double**. This allowed me to make one version of all of the complex number’s init and other functions. I also had BaseNumeric add a couple of helper functions to **Int** and **Double** to return **Double** and **Int** versions of the number. This reduced code duplication in my complex number representation.

BaseNumeric also needed to override the -, +, *, and / operators. They are all very similar. We’ll look at just the override for the – operator.

func - (lhs:BaseNumeric, rhs:BaseNumeric) -> BaseNumeric{ if lhs is Double || rhs is Double { return lhs.asDouble() - rhs.asDouble() } else{ return lhs.asInt() - rhs.asInt() } }

This version of the – operator can be placed between two BaseNumeric values, be they **Ints**, **Doubles**, or some combination of those, and returns a BaseNumeric. The operator checks the type to see if either BaseNumeric is a **Double**. If at least one is, then the result is calculated as a **Double**. If not, the result is calculated and returned as an **Int** BaseNumeric.

With the BaseNumeric protocol extending both **Int** and **Double**, I could now create a struct to represent complex numbers. I called it Complex. Complex implements Swift’s standard **Printable** protocol so using **println**() is easy. Implementing **Printable** meant I needed to add a calculated property of type **String** called **description**.

Following this same pattern, I added two custom calculated properties for the common complex number calculations modulus and conjugate. While you may not be dealing with complex numbers yourself, calculated properties in your code will work the same way. They are declared as variables, the return type is declared, the calculation is done, and a value is returned.

import Foundation struct Complex:Printable{ var real:BaseNumeric var imaginary:BaseNumeric var description: String{ return "\(self.real) + \(self.imaginary)i" } var modululus: Double{ let squaredReal = real * real let squaredImaginary = imaginary * imaginary return sqrt((squaredImaginary + squaredReal).asDouble()) } var conjugate: Complex{ let inversImaginary = imaginary * -1 return Complex(real: real, imaginary: inversImaginary) } func combine(rhs:Complex, combineBehavior:(BaseNumeric, BaseNumeric) -> BaseNumeric) -> Complex{ var realPart = combineBehavior(self.real, rhs.real) var imaginaryPart = combineBehavior(self.imaginary, rhs.imaginary) return Complex(real: realPart, imaginary: imaginaryPart) } }

I also added a combine function. This function allowed me to do both addition and subtraction of my Complex structs with one set of code rather than duplicate the code for both behaviors. To accomplish this, I needed to pass an instance of a Complex to combine with the ‘self’ instance, and a closure, called combineBehavior in the parameter list. The closure would either add or subtract the component pieces of the Complex structs depending on if I wanted addition or subtraction. Calling the combine function in an overloaded version of the + operator shows how to pass the closure.

func +(lhs: Complex, rhs: Complex) -> Complex{ return lhs.combine(rhs, combineBehavior: {(leftValue:BaseNumeric,rightValue:BaseNumeric) -> BaseNumeric in return leftValue + rightValue }) }

Since + is defined by Swift as an infix operator, I didn’t need to declare it myself. For a discussion of overloading standard operators and creating custom operators please see my previous posting on that topic.

In addition to the + and – operators, I overloaded the * and / operators for my Complex class. They calculate the multiplication and division of complex numbers directly since there is not common code between these operators that could be shared.

Now I can create complex numbers using the Complex structure.

let first = Complex(real: -2, imaginary: 3) let second = Complex(real: 1.0, imaginary: 2.0)

and manipulate them using the overloaded operators.

let difference = first - second println("difference: \(difference)") let product = first * second println("product: \(product)") let quotient = first / second println("quotient: \(quotient)")

This makes it much easier to create, manipulate, and display complex numbers.

## Leave a Reply