Dipping Toe Further into Swift – Generics Edition
Work developments have prevented me from doing a lot of iOs, so as things are heating up with Swift and functional programming, my main involvement is reading. But I was reading [this post][macroPost] by Andrew Bancroft on using Swift functions to replace C macros in your code, and I noticed that the author used an Int-typed function to replace a macro, which is fine, but misses the flexibility of a macro.
Based on all my reading, I immediately thought of generics. It seemed like it should be super easy to replace
func squareNumber(n: Int) -> Int {
return n * n
}
With
func squareNumber<T>(n: T) -> T {
return n * n
}
But, of course it wasn’t. Basically, I had forgotten/didn’t realize that when you have a generic type, you need to tell the compiler how your type is going to behave with various operators. I struggled with this for a bit, finally stumbling across [this post][natePost] by Nate Cook, now of NSHipster who perfectly answered my question. So the form looks mostly as I expected, but the extension of the type looks like this, which isn’t pretty, but most of the boilerplate is a one time addition for mathematical functions:
extension Double : NumericType {}
extension Float : NumericType {}
extension Int : NumericType {}
extension Int8 : NumericType {}
extension Int16 : NumericType {}
extension Int32 : NumericType {}
extension Int64 : NumericType {}
extension UInt : NumericType {}
extension UInt8 : NumericType {}
extension UInt16 : NumericType {}
extension UInt32 : NumericType {}
extension UInt64 : NumericType {}
protocol NumericType {
func +(lhs: Self, rhs: Self) -> Self
func -(lhs: Self, rhs: Self) -> Self
func *(lhs: Self, rhs: Self) -> Self
func /(lhs: Self, rhs: Self) -> Self
func %(lhs: Self, rhs: Self) -> Self
init(_ v: Int)
}
func squareNumber<T: NumericType>(n: T) -> T {
return n * n
}
println("one: \(squareNumber(5))")
So, woohoo for learning something!
[macroPost]: http://www.andrewcbancroft.com/2015/01/29/converting-complex-objective-c-macros-swift-functions/
[natePost]: http://natecook.com/blog/2014/08/generic-functions-for-incompatible-types/