I started a new iOS project about 4 months ago in Swift just to learn the language. While I've been developing it, I found myself almost never using tuples in the entire program. This is because I'm really used to Java and Objective-C which do not have tuples.
I've heard some great things about tuples, and Apple seemed very excited about adding them into Swift, but it seems like I'm having a hard time finding a really useful case for them.
I understand and use them for one thing so far: quick-class replacer. Instead of making a new class for the sole purpose of keeping a few properties together, use a tuple instead. But even then I've only used a tuple for that once, because many times those properties affect each other, so those methods that alter those properties are better contained in a class with those properties. So is this really an advantage?
But what are some other really useful design patterns used in OOP (or Swift) that people who are new to tuples should know about?
Thanks!
A couple of examples from the standard library may help.
A common need is to return not just one value from a function, but two different values. So for example, in the _IntegerArithmeticType protocol, there is:
static func addWithOverflow(lhs: Self, _ rhs: Self) -> (Self, overflow: Bool)
That is, it returns the new value, plus a boolean indicator of whether there was an overflow:
let i: UInt8 = 0xFF
let (j, overflow) = UInt8.addWithOverflow(i, 1)
if overflow { println("Oh noes!") }
Without a tuple, you would have to resort to an inout for one of the results, or return another struct.
The Dictionary collection holds two types for its element, a key and a value. These are often bundled together, so Dictionary defines a type, Element as a tuple of the two:
struct Dictionary<Key : Hashable, Value> : CollectionType, DictionaryLiteralConvertible {
typealias Element = (Key, Value)
}
Then, when you iterate over a dictionary, each element you get is this pair, and the built-in destructuring of tuples allows you to conveniently separate them into two:
// either treat them as a pair:
for element in myDictionary { }
// or destructure them:
for (k, v) in myDictionary { }
Now, in theory, both these examples could have been done by defining new structures. So for example with the overflow case:
struct ResultWithOverflow<T: _IntegerArithmeticType> {
let value: T
let overflow: Bool
}
static func addWithOverflow(lhs: Self, _ rhs: Self) -> ResultWithOverflow<Self>
However, it’s important to understand that here, tuples are not just being used because it’s a pain to have to define this extra struct (even though this is true). It’s more because this extra struct is clutter – it gets in the way of reading the function. If you wanted to know what addWithOverflow did, you’d have to go look up what ResultWithOverflow was. Instead, with the tuple, it’s quite clear there at the function definition what is being returned.
Similarly, if there were a DictionaryElement struct that was what the dictionary held as its element, that would also be an added complication that could get in the way of understanding how dictionaries worked.
This is a trade-off, obviously, and if you use tuples everywhere instead of defining proper structures, you’ll go too far the other way and make your code unreadable. But in cases where the usage is one-off and lightweight, they’re both easier to write and clearer to read.
@Airspeed Velocity gives a really good answer! I just wanted to add how useful Tuples can when used with switch statements. For example:
let point = (x: 10, y: 5)
switch point {
case (10, 5):
println("Point at (10, 5)")
case (-10...10, 5):
println("Point where y = 5 and x lies in the range [-10, 10]")
case (_, 5) :
println("Point with y = 5")
case (let x, _) where x % 2 == 0:
println("Point with x that is a multiple of 2 (x = \(x))")
default:
println("A Point")
}
Obviously, that's not the kind of example you'd really use, but I think it demonstrates some of the capabilities of Tuples.
Apple's The Swift Programming Language discusses more about Tuples, here's the link if you haven't seen it already: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID309
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With