inessential by Brent Simmons

The Liscio Approach to Variants in Swift

In two recent posts — see how we keep calm and carry on? We’re back to tech topics — I wrote about implementing variants in Swift 2.0.

(See Swift question: Enum vs. Struct for Variants and, before that one, Swift Protocols Question.)

In both cases I was definitely thinking like an Objective-C programmer — I was thinking about how to wrap native types in a variant type.

One approach was to use an enum with associated types, which is much like using tagged unions in C. Another approach was to create a different struct for each under-the-hood value type and have them all conform to a Value protocol.

Chris LiscioCapo author (Capo is genius, FYI) — suggested another approach: Don’t wrap. Don’t box. Just use the native types directly.

That is, instead of creating something like this…

protocol Value {
  func valueBySmashingOtherValue​(value: Value) -> Value
}

BoolValue : Value {
  let value: Bool
  func valueBySmashingOtherValue​(value: Value) -> Value {
    // do something and return a Value
  }
}

IntValue : Value {
  let value: Int
  func valueBySmashingOtherValue​(value: Value) -> Value {
    // do something and return a Value
  }
}

etc.

…do this instead:

protocol Value {
  func valueBySmashingOtherValue​(value: Value) -> Value
}

extension Bool : Value {
  func valueBySmashingOtherValue​(value: Value) -> Value {
    // do something and return a Value
  }
}

extension Int : Value {
  func valueBySmashingOtherValue​(value: Value) -> Value {
    // do something and return a Value
  }
}

etc.

That is, extend the native types instead of wrapping them.

In Objective-C you can’t extend BOOL or NSInteger since they’re not object types, but in Swift you can extend Bool and Int and similar types.

At my stage in learning Swift I wouldn’t have thought of this — but Chris did. (Thanks, Chris!)

(The advantages of this approach are, I hope, self-evident.)

PS The code above hasn’t been checked to see if it compiles. (Written directly in MarsEdit.) But you get the idea.

PPS I am frequently tempted to write that Objective-C is my lightsaber. But I don’t think that’s fair. I think it’s more that I’m still learning how Swift can be elegant — and Chris’s approach here counts as an instance of elegance.