Tuples Are The New Struct

I published a "revised" look at this that uses a less controversial example as people were getting stuck on this example being an Either<T,U> (enum based) instead of looking at structs vs. tuples.

: .info

I've been playing around with using named tuples instead of structs for pure data types. One such use case was in returning errors from a function.

Let's say we a function foo and we want to return an Int or an Error?. There are lots of ways to model this: structs, enums, tuples, inout parameters, global error state, etc…

Of course, each has their positives and negatives. However, I want to look at what the difference of the struct and the tuple implementation looks like.

The function definition will look like this:

func foo() -> IntOrError {}

The struct would look like this (Error is my own custom error type, you could use NSError too):

struct IntOrError {
    let value: Int
    let error: Error?
}

The tuple would look like this:

typealias IntOrError = (value: Int, error: Error?)

Usage of the two looks exactly the same:

let result = foo()
if let error = result.error {
    println("Uh oh! An error occurred")
}
else {
    println("The value is: \(result.value)")
}

So should you use tuples? Well, I don't know. =) There are two big disadvantages of the tuple approach:

  1. No generics support; I cannot create: typealias ErrorOf<T> = (value: T, error: Error?). I consider this a deficiency in the generics system of Swift though.
  2. No ability to add functionality to the type itself; essentially no OOP-style programming. This also extends to specific initializers.

However, the I see some benefits for the tuple approach too:

  1. Much faster prototyping while maintaining good readability of code
  2. Currently (as of Beta 6), tuples as return types perform much better than structs. This should get better though. Update: I think the root cause of this was due to rdar://18111139: Swift: Optimizer Perf Bug with inline/external class definitions.
  3. "Upgrading" to a full-blown struct requires only updating the definition of your code (beware, this would be a breaking change for code linking your code though).

If all you need is a dumb data type, try out the named tuple!

Tuples Are The New Struct