Yesterday I wrote about thinking about using tuples in place of your dumb data types. However, my example used a class of problem that was typically modeled using an Either<T,U>
type. That, understandably, added some confusion that was not intended.
Today, let's instead take a look at an example that is hopefully a little less contentious: the Point
type (just two-dimensional).
At a quick glance, I see the following as ways in which we might model the Point
type as a tuple, struct, class, or even as an enum.
Here's some sample uses for each of them:
Tuple
typealias Point = (x: Int, y: Int)
let p = Point(2, 6) // Point(x: 2, y: 6) is also valid
println("(x, y) = (\(p.x), \(p.y))")
Struct
struct Point {
var x: Int
var y: Int
}
let p = Point(x: 2, y: 3)
println("(x, y) = (\(p.x), \(p.y))")
Class
class Point {
var x: Int
var y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
let p = Point(x: 2, y: 3)
println("(x, y) = (\(p.x), \(p.y))")
Enum
enum Point {
case Components(Int, Int)
}
let p = Point.Components(2, 3)
switch p {
case let .Components(comp):
println("(x, y) = (\(comp.0), \(comp.1))")
}
Now, each of the above approaches has positives and negatives to their approaches. However, to me, the tuple has all of the right behavior out of the box. The enum based approach is the most verbose and I'm unclear of any distinct advantage it has over both the tuple and struct/class options.
If you're anything like me, you might tend to write your code in stages:
- There's the initial prototyping and scaffolding to make sure your thoughts apply to code.
- Then the roughing in with types and better names.
- Finally we get to the flushed out public API surface.
Along the way there is a lot of back and forth between the stages. I tend to start with the least amount of code so that it's easier to through away. So, in flushing out my API, the Point
might remain a tuple throughout all of the stages.
Also, by starting with a tuple, I have to specifically ask myself the question: do I really need to add this function or private data here? Is there a better way to model this?
Don't forget about the tuple. Of course, your mileage may vary.