# Protocol extensions and the death of the pipe-forward operator

So a while back I wrote about using some functional programming techniques in Swift to solve the Luhn credit card checksum problem.

One of the suggestions in the article was defining and using `|`> to avoid the annoying tennis-match bouncing left and right between free functions and methods.

Since 2.0 came out, I’ve been thinking I really needed to update some of my articles to the new syntax, and started on this one. Except as protocol extensions are the new hotness, using them would probably be the more “Swift-y” way of writing this. So here’s a solution using new 2.0 features.

As a reminder, here’s the requirements, in the form of wikipedia’s description of the algorithm:

1. From the rightmost digit, which is the check digit, moving left, double the value of every second digit; if the product of this doubling operation is greater than 9 (e.g., 8 × 2 = 16), then sum the digits of the products (e.g., 16: 1 + 6 = 7, 18: 1 + 8 = 9).
2. Take the sum of all the digits.
3. If the total modulo 10 is equal to 0 (if the total ends in zero) then the number is valid according to the Luhn formula; else it is not valid.

So, here in turn are each of the components, all written as extensions.

First, converting characters to integers. Similar to `String.toInteger` becoming `Int.init(String)`, here’s an extension of `Int`:

```extension Int {
init?(c: Character) {
guard let i = Int(String(c)) else { return nil }

self = i
}
}
```

Here I’m using `guard` to check the value is convertible and return `nil` if not. Yes, I know, this is hardly different from an `if let/else`, but I like the use of `guard` whenever I want to handle a failure case like this “up front”.

It would be nice to make this a protocol extension rather than an extension of `Int`. All the std lib integer types support a from-string initializer, after all. But this would involve creating a protocol like `IntegerStringConvertible` and then extending all the integers to conform to it, since such a common grouping doesn’t exist.

The previous post defined `mapSome`, which takes a transformation function that returns an optional, and returns an array of only those values that weren’t transformed into `nil`:

```extension SequenceType {
func mapSome<U>(transform: Generator.Element -> U?) -> [U] {
var result: [U] = []
for case let x? in lazy(self).map(transform) {
result.append(x)
}
return result
}
}
```

(the `for case let x?` is using the new pattern-matching syntax that lets you `for` over only the non-nil values in a sequence)

But as of 2.0, `flatMap` has been enhanced to do this exact thing. So we no longer need to define it.

We’re going to use this along with the character-to-integer initializer to extract only the numbers from the credit-card string, like so, using the new 2.0b2 feature of using an `init` as a function:

```":123-456:".characters.flatMap(Int.init)
// returns [1,2,3,4,5,6]
```

(note, we have to do this on the `.characters` view now, since `String` is no longer itself a sequence).

Next, the a function that let you apply a transformation only to every n th value in a sequence:

```extension SequenceType {
func mapEveryNth(n: Int, transform: Generator.Element -> Generator.Element)
-> [Generator.Element]  {

// enumerate starts from zero, so for this to work with the nth element,
// and not the 0th, n+1th etc, we need to add 1 to the ifIndex check:
let isNth = { (\$0 + 1) % n == 0 }

return enumerate().map { i, x in
isNth(i) ? transform(x) : x
}
}
}
```

Then, a `sum` on any sequence that contains integers:

```extension SequenceType where Generator.Element: IntegerType {
func sum() -> Generator.Element {
return reduce(0, combine: +)
}
}
```

and an extension on any integer to check if it’s a multiple of another:

```extension IntegerType {
func isMultipleOf(of: Self) -> Bool {
return self % of == 0
}
}
```

And finally, to put them all together into a single extension to `String` that validates the checksum:

```extension String {
func luhnchecksum() -> Bool {
return characters
.flatMap(Int.init)
.reverse()
.mapEveryNth(2) { \$0 < 5 ? \$0*2 : \$0*2 - 9 }
.sum()
.isMultipleOf(10)
}
}

let ccnum = "4012 8888 8888 1881"
print( ccnum.luhnchecksum() ? "👍" : "👎" )
```

This now looks very similar to the version that used the `|`> operator – but without having to define any custom operator at all. Which feels like a win to me.

Yes, you could have done all this before using extensions of concrete objects in 1.2. But most of these extensions are more general than that – for example, `mapSome` can work on the string character view, but also arrays, dictionaries, sets.

Anyway, now back to playing with beta 2…

# Changes to the Swift Standard Library in 2.0 beta 1

OK don’t panic – it might look like a lot has changed, but not really. It’s more… transformed. For the better. Nothing the migration assistant shouldn’t be able to handle.

By far the biggest change in the standard library is due to the new protocol extensions. The free `map` function is dead, long live the `map` extensions to `CollectionType` and `SequenceType`. Which means now you only ever call `map` as a method – no more shuttling back and forth between functions and methods like you’re watching a tennis match.

To show how this works, let’s define my usual example, `mapSome`:

```extension SequenceType {
/// Return an `Array` containing the results of mapping `transform`
/// over `self`, discarding any elements where the result is `nil`.
///
/// - Complexity: O(N).
func mapSome<U>(@noescape transform: Generator.Element -> U?) -> [U] {
var result: [U] = []
for case let x? in self.map(transform) {
result.append(x)
}
return result
}
}
```

You can use this in the method-calling style, for example, with the brand new double-from-string failable initializer:

```let a = ["3.14", "foo", "6.02e23"]
let doubles = a.mapSome { Double(\$0) }
print(doubles) // no more println!
// prints [3.14, 6.02e+23]
```

Incidentally, this implementation of `mapSome` uses the new pattern-matching capabilities of `for` to filter out nils. The `case let` syntax is matching an enumeration – and since optionals are enumerations, it works for them too. `for` has also acquired `where` clauses:1

```let isEven = { \$0%2 == 0 }
for even in 0..<10 where isEven(even) {
print(even)
}
```

But there’s more. You can constrain the extension, similar to how you would constrain a placeholder in a generic function. And this means you can give protocols methods that only apply when they have certain properties. For example, there’s now a version of sort on arrays (or any other collection type) that doesn’t need to be given a isOrderedBefore argument, so long as the array contents are `Comparable`. There’s still an overload that takes a closure if you want to do something more custom, but if you just want the default behaviour (ascending), you don’t need one.

For example, here’s an implementation of `all` that returns true if all the values are equal to a certain value:

```// a version that only applies when the contents of the
// sequence are equatable
extension SequenceType where Generator.Element: Equatable {
/// Return `true` iff every element of `self` is `x`.
func all(equalTo: Generator.Element) -> Bool {
// of course, contains is now a method too
return !self.contains { \$0 != equalTo }
}
}

// and an unconstrained version where the caller supplies a predicate
extension SequenceType {
/// Return `true` iff every element of `self` satisfies `predicate`.
func all(criteria: Generator.Element -> Bool) -> Bool {
return !self.contains { !criteria(\$0) }
}
}

[1,1,1].all(1)       // true

let isEven = { \$0%2 == 0 }
[2,4,6].all(isEven)  // true
```

As a result, the number of free functions in the standard library has dropped from 101 down to 77. I wonder how far this will go – will it eventually just be a motly crew of `unsafeBitCast` and company left? Should `abs()` become an extension of `SignedNumberType`? And now it can be, should it be a property? This and more in the next exciting installment of Swift…

Grab Bag

Here are a few other changes to the standard library:

• `Array.withUnsafeMutableBufferPointer` has acquired a warning: do not use the array itself while calling it, only refer to the contents via the pointer. Presumably so updates to the array can potentially be deferred to after it’s finished executing. Same for `ContiguousArray` and `Slice`.
• They’ve also had some of their internal-type initializers privated.
• Some of the `_`-prefixed protocols have started to disappear. For example `_BidirectionalIndexType` is gone, and `BidirectionalIndexType` now has its `predecessor` method. And `_Comparable` is gone, `Comparable` now containing its < operator.
• `CollectionOfOne` and `EmptyCollection` now have a `count` property – just in case you want to check they’re not misleading you.
• So now for the start of the great extensionizing… `CollectionType` now has `isEmpty`, `count`, `map`, `filter`, `first`, `last`, `indexOf`, `indices` and `reverse`. So these are now available as methods on all collections. Corresponding methods in existing collections have been removed.
• `indexOf` is what `find` used to be called. And it now has a version that takes a predicate.
• An `ErrorType` protocol has been added to support the new error handling feature.
• `Printable` and `DebugPrintable` protocols are now the more descriptive `CustomStringConvertible` and `CustomDebugStringConvertible`
• There are also `CustomReflectable`, `CustomLeafReflectable` and `CustomPlaygroundQuickLookable` protocols for tweaking how your type behaves in a playground.
• And there’s a new `Mirror` type for returning from the `CustomReflectable` protocol.
• There’s a new `DictionaryLiteral` type, so you can now use the `[:]` syntax for more than just dictionaries without worrying about duplicate keys getting coalesced.
• As mentioned above, `Double`, `Float` and `Float80` have acquired failable initializers from strings.
• And the integers now have the same, replacing the `toInt` method on string. And they take a `radix` argument! You still can’t tell from the headers what default values are for defaulted arguments, but I'm guessing this one is 10.
• `FloatingPointType`’s `_toBitPattern` and `_fromBitPattern` are gone. I guess you can use `unsafeBitCast` if you like bits.
• All the lazy collections have acquired an `underestimateCount`.
• `MutableCollectionType` is a good example of extensions with `where` clauses – such as requiring the collection also be random-access in order for it to have `partition` and `sortInPlace` support.
• `SequenceType` sucks in `contains`, `sort`, `underestimateCount`, `enumerate`, `minElement`, `maxElement`, `elementsEqual`, `lexicographicalCompare` and `flatMap`
• `elementsEqual` being the new name for the `equal` function that compares two sequences.
• and `minElement` and `maxElement` now return optionals in case of empty sequences, and also now have versions that take `isOrderedBefore` closures.
• There’s a new `SetAlgebraType` protocol, for types that are “a generalized set whose distinct elements are not necessarily disjoint”. `Set` does not conform to it (though it has all the properties it requires).
• A type that does conform to it is `OptionSetType` protocol, for bitfield enums.
• `print` is gone! Now `println` is `print` and old `print` is `print(1, newLine: false)`
• `toString` is no more. Just use the `String` initializer that takes any type (and has a similar hierarchy of fallbacks)
• `readLine` reads from the standard input, returning an optional `String` so you can `while let` over it.

Protocol Extensions are Defaults

Silly jokes aside, there’s a good reason for why `CollectionOfOne` and `EmptyCollection` have implementations of `count`. If a protocol has a default implementation, but you know your specific type can do it faster because of how it works internally, a specific implementation will take precedence over the protocol version.

So for example, suppose we implemented the next (but fairly pointless) logical collection type: `CollectionOfTwo`:

```struct CollectionOfTwo<T>: CollectionType {
let first: T, second: T
subscript(idx: Int) -> T {
precondition(idx < 2, "Index out of bounds")
return idx == 0 ? first : second
}
var startIndex: Int { return 0 }
var endIndex: Int { return 2 }
}

let two = CollectionOfTwo(first: "42", second: "420")
",".join(two)  // “42,420"
```

Notice, that I didn’t need to define a generator at all – due to this handy new protocol extension:

```// CollectionType conforms to _CollectionGeneratorDefaultsType
// which is extended with:
extension _CollectionGeneratorDefaultsType {
func generate() -> IndexingGenerator<Self>
}
```

Anyway because `CollectionOfTwo` conforms to `CollectionType` it gets a `count` property for free. But it gets them by subtracting the end index from the start, which is quite a roundabout way of doing it. So you can instead give it a hardcoded value by explicitly implementing it:

```extension CollectionOfTwo {
var count: Int { return 2 }
}
```

Now, when `count` is called, it will run this code instead of the default.

Protocols can also replace the default implementations of other protocols they conform to – hence `CollectionType` defines `map` even though `SequenceType` does too.

While we’re implementing simple little types – the default string rendering of custom types is now a lot nicer. Even though it doesn’t yet conform to `CustomStringConvertible`, if you print out `CollectionOfTwo` you’ll get something that looks like `CollectionOfTwo(first: 42, second: 420)` which is much nicer that the `__lldb_expr_11.CollectionOfTwo` you used to get.

Strings are No Longer Collections

Something that might take you by surprise – `String` no longer conforms to `CollectionType`. Though it has all the required properties (just writing `extension String: CollectionType { }` without any implementation works), it’s no longer tagged as such. This is apparently due to concerns that, even with the `Character` representation, there were ways in which using collection algorithms on strings could produce non-Unicode-correct results.

Of course, you still need to manipulate strings, so rather than just resorting to staring at them extra intensely, you can use the new `CharacterView` accessible via the `characters` property:

```let s = "comma,separated,strings"
let fields = split(s.characters) { \$0 == "," }.map { String(\$0) }
```

Since `String`'s `Index` is just a typealias for `String.CharacterView.Index`, you can use them interchangeably:

```let s = "Hello, world!"
if let comma = s.characters.indexOf(",") {
print(s[s.startIndex..<comma])
}
```

Nonetheless, the fact that you have to switch to a character-based view on the string rather than operate on it directly should act as a reminder that you might be doing something that doesn’t behave correctly under all edge cases.

Type-Erased Containers

Finally, there are now a collection of “type-erased” container types available: `AnyBidirectionalCollection`, `AnyRandomAccessCollection` and `AnyForwardCollection` (and associated indexes), plus `AnyGenerator` and `AnySequence`. These could be used, for example, to bully different kinds of collection into being in the same container:

```let set: Set = [1,2,3]
let array = [4,5,6]
let anySet = AnyForwardCollection(set)
let anyArray = AnyForwardCollection(array)
let anys = [anySet,anyArray]
anys.flatMap { \$0 } // [2, 3, 1, 4, 5, 6]
```

However, this is probably not all that useful. Despite the name, this isn’t like the `Any` type – you can’t cast back into the original type, it’s more a one-way trip.

This is more useful when you want to expose an internal collection without exposing exactly what that collection type is. Instead you could create an `AnyXXXCollection` from your internal value, and return that, safe in the knowledge users of your class won’t complain when you switch to a different internal data structure later on.

Well that’s it. The standard library has some sparkly new online documentation. And as part of the WWDC sample code, there’s a playground all about the Swift standard library that is worth checking out. Also it looks like the developer forums for Swift no longer require a developer login to read either, if you want to take a look without registering.

Here’s to a future using all this stuff on the back end once the port to Linux is available!

1. Of course, you wouldn’t write this would you – you’d write `for even in stride(from: 0, to: 10, by: 2)`, right?