Randomly Lazy

In the previous article on extending lazy, we extended the lazy views with first_n, which returned a sequence of the first n elements of a sequence.

But this isn’t great if what you passed in was a random-access indexed collection. Where possible, it’s nice to retain random access on the output of your lazy function. The lazy map does this, for example. If you pass an array into lazy then call map, the collection you get back is a LazyRandomAccessView, and you can index randomly into it just like you could into an array.

To do this for first_n, we need a struct that implements Collection, takes a Collection as an initializer plus a count n, and layers a view over the top of that collection that only exposes the first n elements.

Or, in the more general case, a view that takes a collection and a sub-range within that collection. Here it is:

struct SubrangeCollectionView<Base: Collection>: Collection {
    private let _base: Base
    private let _range: Range<Base.IndexType>
    init(_ base: Base, subrange: Range<Base.IndexType>) {
        _base = base
        _range = subrange
    }

    var startIndex: Base.IndexType {
      return _range.startIndex
    }
    var endIndex: Base.IndexType {
      return _range.endIndex
    }

    subscript(idx: Base.IndexType)
        -> Base.GeneratorType.Element {
        return _base[idx]
    }

    typealias GeneratorType
        = IndexingGenerator<SubrangeCollectionView>
    func generate() -> GeneratorType {
        return IndexingGenerator(self)
    }
}

This sub-range collection view is so useful that I was sure it was somewhere in the Swift standard library. That’s partly why I wrote this article on collection and sequence helpers – as a side-effect of going line by line looking for it. I’m still expecting someone to reply to this article saying “no you fool, you just use X”. If you are that person, call me a fool here.

The Sliceable protocol seems designed to provide this function. It requires a collection to typealias a SliceType and implement a subscript(Range)->SliceType method. But you need the collection to implement sliceable, which seems overly restrictive, whereas the view above works for any collection.

SubrangeCollectionView enables you to pass in a sub-range of any collection to any algorithm that takes a collection or sequence. For example:

let r = 1...10
let halfway = r.startIndex.advancedBy(5)
let top_half = SubrangeCollectionView(r,
                subrange: halfway..<r.endIndex)
reduce(top_half,0,+)  // returns 6+7+8+9+10

A nice feature is that if you pass a subrange collection into an algorithm that returns an index, such as find, the index returned can also be used on the base collection. So in the example above, if you ran if let idx = find(top_half,8), you could then use idx on not just top_half[idx], but also r[idx].

Operating on subranges is a capability that C++ developers, used to the STL, will be missing from Swift collection algorithms. In the STL, operations on containers are performed not by passing the container itself to the algorithm, but instead by passing two iterators on that container defining a range.

For example, here is the definition of the find algorithm in the C++ STL compared to the Swift version:

// C++ std::find
template <class InputIterator, class T>
  InputIterator find
    (InputIterator first, InputIterator last, const T& val);

// Swift.find
func find
  <C: Collection where C.GeneratorType.Element: Equatable>
    (domain: C, value: C.GeneratorType.Element) -> C.IndexType?

While Swift.find takes a collection as its first argument, std::find takes a first and last iterator.

STL container iterators are similar to Swift collection indices, in that they can be forward, bidirectional or random, and are used to move up and down the collection. Like Swift indices, the end iterator points to one past the last element – the equivalent of Swift.find returning nil for not found would be std::find returning end.

But unlike Swift indices, STL iterators model C pointer-like behaviour, so they are dereferencable. To get the value the iterator points to, you don’t have to have access to the underlying container, using something like Swift’s subscript. To get the value at first, you call *first. This is why std::find doesn’t need to take a container in it’s input. It just increments first until either it equals last, or *first equals val.

There are lots of reasons why the STL models iterators like this: because it’s like pointers into C arrays; because it dodges memory management issues (which won’t apply to Swift) etc. But also because, with this model, every algorithm will work just as well on a sub-range of a container as on the whole container. You don’t have to pass the starting or ending iterator for the container into find, you can pass in any two arbitrary points.1

Swift indices, on the other hand, are pretty dumb beasts. They don’t have to know about what value they point to or what collection they index. Heck, the index for Array is just an Int.2

For all the advantages of Swift’s just passing in collections as arguments has (it looks a lot cleaner, doesn’t confuse beginners),3 it lacks this ability to apply algorithms to subranges. SubrangeCollectionView gives you that ability back.

Anyway, back to the original problem, which was to enhance LazyRandomAccessView with a version of first_n that returns another LazyRandomAccessView. With the help of SubrangeCollectionView, here it is:

extension LazyRandomAccessCollection {
  func first_n
    (n: LazyRandomAccessCollection.IndexType.DistanceType)
    -> LazyRandomAccessCollection<SubrangeCollectionView<LazyRandomAccessCollection>> {
      let start = self.startIndex
      let end = min(self.endIndex, start.advancedBy(n))
      let range = start..<end
      let perm = SubrangeCollectionView(self, subrange: range)
      return lazy(perm)
    }
}

let a = [1, 2, 3, 4, 5, 6, 7]
let first3 = lazy(a).first_n(3)
first3[1]  // returns 2

One final interesting question is whether to do the same for forward and bidirectional lazy views as well. The problem here is computing the endIndex for the view. Unlike with a random-access index, you can’t just advance them by n in constant time. It takes O(n) because the index has to be walked up one by one. For this reason, I’d stick with returning sequences for these.


  1. Of course, you can also pass a later iterator to first than to last, at which point, kaboom! A risk which passing in the container itself eliminates. 
  2. Of course, you could write an über-index type for your collection, that did understand about what it pointed at. Maybe you could even overload the * operator for it to dereference itself. 
  3. And lets face it, you operate on the whole collection 99.9% of the time. 

Collection and Sequence Helpers

Before the next installment about laziness, an aside about sequence and collection helpers.

In the previous article, I used a couple of helper objects to generate sequences without having to implement a whole sequence class. The Swift standard library provides quite a few of these, which I describe below.

I’m omitting the view classes returned by lazy, map, filter, enumerate and reverse, as they are tightly associated with their creating function and probably shouldn’t be used as stand-alone things.

CollectionOfOne
When you have a single variable, and you want a collection containing just it (for example, you want to pass it into a function that expects a collection).

CollectionOfOne uses GeneratorOfOne (see below) as its generator.

let i = 42
let just_one = CollectionOfOne(i)
just_one[just_one.startIndex] // returns 42
countElements(just_one) // returns 1
just_one.element // returns 42

EmptyCollection
When you want an empty collection containing none of a specific type. This is only really useful when you specifically don’t want that collection to be an Array for some reason (like in a unit test).

EmptyCollection uses EmptyGenerator (see below) as its generator.

let empty = EmptyCollection<Int>()
countElements(empty) // returns 0

EmptyGenerator
Has no public init, psych! Use GeneratorOfOne, see below.

GeneratorOf: Use Case 1
When you want a generator that serves up elements based on a closure you supply.

var infinite_ones = GeneratorOf { 1 }
infinite_ones.next() // returns 1?
infinite_ones.next() // returns 1?

var i = 0
var naturals = GeneratorOf { ++i }
naturals.next() // returns 1?
naturals.next() // returns 2?
naturals.next() // returns 3?

GeneratorOf: Use Case 2
When you want to treat different generators that generate the same type as all the same type. GeneratorOf has an init that takes other types of generators and returns the same type based only the type of their Element.1

let r = 1...3
let rg = r.generate()

let a = [11, 22, 33]
let ag = a.generate()

// this won't compile, rg and ag 
// are different types
var generators = [rg, ag]

let g_of_rg = GeneratorOf(rg)
let g_of_ag = GeneratorOf(ag)
// this array will be of type [GeneratorOf<Int>]
var gofgenerators = [g_of_rg, g_of_ag]
gofgenerators[0].next()  // returns 1?
gofgenerators[1].next()  // returns 11?

GeneratorOfOne: Use Case 1
When you want to serve up a single value once from a generator.

let i = 42
var just_one = GeneratorOfOne(i)
just_one.next() // returns 42?
just_one.next() // returns nil

GeneratorOfOne: Use Case 2
When you want to serve up no values from a generator. If you pass in a variable set to nil, it will act like an EmptyGenerator.

let i: Int? = nil
// GeneratorOfOne.init takes T?, unlike 
// CollectionOfOne.init which takes T
var none = GeneratorOfOne(i)
// 'none' is now a GeneratorOfOne<Int>
// that returns no values.
none.next() // returns nil

GeneratorSequence
When you have a generator that isn’t a sequence, but you need a sequence.

let st = stride(from: 1, to: 7, by: 2)
// StrideTo's generator is a rare example
// of a Generator that isn't also a Sequence.
let stg = st.generate()

for i in stg {
    // compiler error, stg
    // is not a Sequence
}

for i in GeneratorSequence(stg) {
    // works OK
}

Be careful! The example above is fine, because the GeneratorSequence is created for a single use and then disposed of. GeneratorSequence doesn’t bestow magical resetting properties on the generator you give it. If you hand over a GeneratorSequence to some other function that requires a Sequence, that function could try and walk the sequence multiple times, which will have undefined results depending on what kind of generator it is. Generators that don’t declare they’re also Sequences probably don’t for a reason.

IndexingGenerator
When you’re implementing a collection, and the generator doesn’t need to do anything more fancy than use the startIndex and subscript methods to serve up each value. Most of the standard library collections use it.

The tiniest working toy collection. Isn’t it cute:

class TenInts: Collection {
    var startIndex: Int { return 0 }
    var endIndex: Int { return 10 }
    subscript(i: Int)->Int { return i }
    typealias GeneratorType = IndexingGenerator<TenInts>
    func generate() -> GeneratorType {
        return IndexingGenerator(self)
    }
}

let ti = TenInts()
reduce(ti, 0, +) // returns 45

PermutationGenerator
When you have a collection, and you want a Sequence or Generator that is made up of elements of that collection served up in an arbitrary order.

let r = 1...10

let tail = PermutationGenerator(elements: r,
            indices: r.startIndex.successor()..<r.endIndex)
// sequence of 2...10

let every_third = PermutationGenerator(elements: r,
                    indices: stride(from: r.startIndex,
                                to: r.endIndex,
                                by: 3))
// sequence of 1, 4, 7

Repeat
When you want a collection of the same values repeated a specific number of times.

You can change the number of times later, but you can’t change the value that repeats.

var finite_ones = Repeat(count: 100,
                    repeatedValue: 1)
countElements(finite_ones) // returns 100
finite_ones.count = 200
countElements(finite_ones) // returns 200
finite_ones.repeatedValue = 2
// compilation error: 
// repeatedValue is read-only

Repeat uses an IndexingGenerator, and then uses endIndex to control how many elements are generated.

SequenceOf: Use Case 1
When you want a sequence whose generator can be based on a closure you supply.

The difference between GeneratorOf and SequenceOf is subtle. GeneratorOf takes a closure that returns the next value. SequenceOf takes a closure that returns a generator, which if you’re following expected behaviour, will be a freshly reset generator. Chances are you’ll want to use GeneratorOf as the return value of your SequenceOf closure:

let naturals = SequenceOf {
    // I can't get the type inference 
    // grooving here for some reason
    _ -> GeneratorOf<Int> in
    // new i to capture for each
    // fresh generator
    var i = 0
    return GeneratorOf {
        ++i
    }
}

// Can now create multiple
// independent generators:
var n1 = naturals.generate()
var n2 = naturals.generate()
n1.next() // returns 1?
n2.next() // returns 1?
n1.next() // returns 2?
n2.next() // returns 2?

Note, you do not have to wrap GeneratorOf inside SequenceOf just to make it a sequence. GeneratorOf implements Sequence. The big difference is, if you need to reset the generator on each call to generate because the closure has state, you need SequenceOf. If your desired sequence is stateless (say it is an infinite sequence of a single constant, or a infinite sequence of the current time), you only need GeneratorOf.

SequenceOf: Use Case 2
Similar to GeneratorOf, when you want to treat different sequences that generate the same type as all the same type. SequenceOf has an init that takes other types of sequences and returns the same type based only the type of their Element.

let a = [1, 2, 3, 4]
let b = lazy(a).filter { $0%2 == 0 }
// this won't compile, a and b are different types
let seqs = [a, b]
// this will, both elements are SequenceOf<Int>
let seqs = [SequenceOf(a), SequenceOf(b)]

So there you go. Hopefully some of these will save you some typing, if you plan on writing your own collections or sequences, or need to generate some makeshift ones on the fly.


  1. My guess is, the second init creates a closure that wraps the supplied generator and returns a GeneratorOf that calls it. That’s probably a pretty interesting idea to play with some other time. 

Working at being lazy

As teased in the previous article, suppose you want a new kind of lazy evaluation. You want to be able to generate a lazy sequence that represents the first n values of a container.

Here’s how you could add it to LazyRandomAccess:

extension LazyRandomAccessCollection {
    func first_n
      (n: LazyRandomAccessCollection.IndexType.DistanceType)
      -> LazySequence<
           PermutationGenerator<
             LazyRandomAccessCollection,
             Range<LazyRandomAccessCollection.IndexType>
           >
         > {
        let start = self.startIndex
        let end = min(self.endIndex, start.advancedBy(n))
        let range = start..<end
        let perm = PermutationGenerator(elements: self, indices: range)
        return lazy(perm)
    }
}

This uses PermutationGenerator, which is a lazy view class that returns a (sub-)sequence of values from a collection in the order given by another collection of indices into that collection. In first_n’s case, the indices are a range of the first n indices (or the full collection if there are fewer than n elements).

The return type of first_n is a bit crackers so I’ve broken it up over multiple lines. It returns a lazy sequence of a permutation generator of a lazy random access collection, permuted by a range of lazy random access collection indices. Phew.1 This is why the lazy function and Swift’s type inference is more than just nice to have, it’s essential. The actual types you are using in a simple function can quickly get to a point where there’s no practical way you could declare them by hand.

The practice of returning another lazy object that wraps the results is copied from the lazy map and filter members, which do the same. Why wrap PermutationGenerator in another LazySequence instead of returning it directly? Chaining mostly I think.2 Without doing that, you’d have to re-lazy the result if you wanted to run more lazy filters on it:

let r = 1...10
// with lazy wrapper
let l = lazy(r).first_n(5).filter(isOdd)
// without lazy wrapper
let l = lazy(lazy(r).first_n(5)).filter(isOdd)

That works for a collection,3 but what about a sequence? How can we generate a new sequence that only returns the first n values?

Instead of declaring that in one shot, we’ll follow the pattern of map and filter and first declare a view:

struct FirstNSequenceView<Base: Sequence> : Sequence {
    private let _n: Int
    private let _base: Base
    init(_ base: Base, _ n: Int) {
        self._base = base
        self._n = n
    }

    func generate()
      -> GeneratorOf<Base.GeneratorType.Element> {
        var i: Int = 0
        var g = _base.generate()
        return GeneratorOf {
            ++i <= self._n ? g.next() : nil
        }
    }
}

This uses GeneratorOf, which takes for its constructor a closure that serves up values for each call to next(). This helps avoid having to manually write a companion generator class when you implement your own sequence (IndexingGenerator is a similar helper that can be used to conform to Sequence when you implement your own Collection). In this case, generate() creates a closure that captures a counter that will count up, returning elements from the sequence until it hits n. It then returns a GeneratorOf that will call that closure each time next() is called on it. Since each time generate() is called, a new closure with a fresh i will be created, this means FirstNSequenceView conforms to the requirement of Sequence that it can be walked multiple times with multiple independent generators.

Now that we have this view, it’s easy to declare first_n for all the lazy views:

extension LazySequence {
    func first_n(n: Int) -> LazySequence<FirstNSequenceView<LazySequence>> {
        return lazy(FirstNSequenceView(self,n))
    }
}
extension LazyForwardCollection {
    func first_n(n: Int) -> LazySequence<FirstNSequenceView<LazyForwardCollection>> {
        return lazy(FirstNSequenceView(self,n))
    }
}
extension LazyBidirectionalCollection {
    func first_n(n: Int) -> LazySequence<FirstNSequenceView<LazyBidirectionalCollection>> {
        return lazy(FirstNSequenceView(self,n))
    }
}
extension LazyRandomAccessCollection {
    func first_n(n: Int) -> LazySequence<FirstNSequenceView<LazyRandomAccessCollection>> {
        return lazy(FirstNSequenceView(self,n))
    }
}

It’s a bit of a hassle having to implement each one separately, but that’s the price you pay for structs that aren’t in a hierarchy. All the more reason to factor the hard part out into a seperate view object.

Does first_n belong as a lazy view member? Unlike map and filter, it doesn’t take a closure so the laziness is less likely to bite you. Maybe take_while, a filter that returned members of an array until a supplied predicate returned false, would have been a better example. But first_n could take a lazy sequence that itself depended on a closure, so the laziness of first_n could still come as a surprise. Also, the chaining is nice. Does this mean other lazy sequences like enumerate should migrate into being lazy class members? I dunno, maybe.

Without the chaining, you have to wrap the results in a function call. But the function call goes on the left, while chained calls go on the right, which results in a confusing ping-pong effect:

let l = lazy(first_n(lazy(r).filter(isOdd),5)).map(...)

The ordering of this is not obvious at first glance, but it’s filter, then first_n, then map. But then where does it end? Should everything get piled into the lazy classes just to benefit from chaining? Nah. The better solution is to implement a pipe forward operator, of which more some other time.


  1. I have a nagging feeling this could be simplified. The Swift standard lazy functions don’t look quite this bad, they use a type of S instead of a type of themselves for the inner parts of the return values of map and filter. But then the compiler doesn’t completely faithfully represent the generic types in the declarations you see in Xcode (which is why there is a lot of T == T in what we see of the Swift standard library). Let me know if can figure out a better way. 
  2. Also, if someone option-clicks the results, it’s obvious at a glance that the results are lazy. 
  3. In fact, while a variant of the permutation version would work for forward and bidirectional collections as well, it’s not a good idea, because advance will take O(n) which is unnecessary, as the next version will show. 

Lazy by name, lazy by nature

When last we discussed lazy collections and sequences, I opened the article with an “ah-hah-hah, this doesn’t do what you might assume” number.1 What map and filter returned were objects that would evaluate and return results lazily on demand, so when you called them, no mapping or filtering took place right away. Instead it happened later, when you accessed the elements of a MapFilterView and its kin.

Well, turns out Apple decided that cleverly not doing what people might expect isn’t necessarily the best move, so as of beta 4, map and filter return an Array. They still take in collections and sequences of any kind, but an array is what they spit out.2

This is probably for the best. If you didn’t realize map computed lazily, you could be surprised when the results changed each time you iterated over a map using a closure like this:

let r = 1...4
var i = 0
let m = map(r) { $0 * ++i }

for e in m {
    // loops over 1, 4, 9, 16
}
for e in m {
    // loops over 5, 12, 21, 32
}

Even the Swift dev team weren’t immune to the unexpected consequences of lazyness. There were some bugs in using FilterCollectionView to populate an Array, as it took two passes, one to determine the array size needed and another to populate the array. A predicate that returned fewer results on the first pass than the second would result in buffer overrun.

Explicitly lazy

Now, with beta 4, there’s no excuses for getting surprised by lazy evaluation. If you still want to be lazy, you first need to pass your sequence or collection into a call to lazy(), which will give you back a lazy view class. What you get back depends on what you pass in – if you pass in a sequence, you’ll get back a LazySequence. If you pass in a collection, you’ll get back one of the lazy collection structs – either LazyForwardCollection, LazyBidirectionalCollection, or LazyRandomAccessCollection.

These views get progressively more features depending on the capabilities of their base. LazySequence has lazy map and filter methods that work like the old lazy map and filter functions, by returning another LazySequence object.

It also has an array property for crystalizing the lazy results into an array. Should you decide at a later point you want to iterate over the collection more than once, you should use this. If you don’t, duplicate iterations will wastefully re-run the mapping or filtering function over and over.

This also means that you can now safely write this:

var i = 0
let lf = lazy(1...5).filter { _ in
    ++i % 2 == 0
}
let a1 = lf.array
// a1 is [2, 4]
let a2 = lf.array
// a2 is [1, 3, 5]
let a3 = lf.array
// a3 is [2, 4]

LazyForwardCollection only adds subscript, since forward-indexable collections can’t do much more than sequences.

Note, filter still returns a sequence, even when called on the lazy collections, to avoid the heartache described above where other collection constructors assumed they could rely a collection’s length being consistent. The results of map can be a collection, because it returns a value for every element in the base no matter what. That collection inherits the index properties of the base.

LazyBidirectionalCollection and LazyRandomAccessCollection add the ability to reverse lazily. So if you wanted to filter just the first few items starting at the back of a collection, you could call lazy(col).reverse().filter { ... }.

The collection returned by reverse can be used wherever you use a regular collection. If you’re a C++ programmer and you liked the benefits of rbegin/rend, this might be what you’re looking for:

let s = "The cat in the hat"
let rs = lazy(s).reverse()
if let idx = find(rs, "h") {
    // idx points to the h of hat
    // not the h of The
}

The lazy factory

How you get the best lazy view class is pretty cool. lazy is actually 4 overloaded generic functions:

func lazy<S: SequenceType>(s: S) -> LazySequence<S>
func lazy<S: CollectionType where S.Index: ForwardIndexType>(s: S) -> LazyForwardCollection<S>
func lazy<S: CollectionType where S.Index: BidirectionalIndexType>(s: S) -> LazyBidirectionalCollection<S>
func lazy<S: CollectionType where S.Index: RandomAccessIndexType>(s: S) -> LazyRandomAccessCollection<S>

When you call lazy, the Swift compiler picks the most specific overload possible, preferring more specialized inherited protocols over base ones. So CollectionType beats SequenceType, because CollectionType inherits from SequenceType. CollectionType where S.Index: RandomAccessIndexType beats CollectionType where S.Index: BidirectionalIndexType because RandomAccessIndexType inherits from BidirectionalIndexType.3 What is returned is an instance of another generic class, that implements a lazy view on any specific collection or sequence.

I don’t know if there’s an official term for this, but I call it a generic factory. It’s similar to the abstract factory design pattern, in that you call a function to get back one of a range of possible concrete types. But in this case, the type determination happens at compile time, and what you get back is not an implementation of an abstract interface, but the actual appropriate concrete type.

This all feels transparent to the caller because of Swift’s type inference capabilities. You call lazy, passing in your base object, assign the result to a variable, and then merrily start using it. But you aren’t constrained to an interface exposing only the common features of the possible concrete classes, like you would be with an interface and absract factory set-up. If you passed in collection that’s capable of it, you get a reverse method.

Other than help pick the best container type, lazy doesn’t do much. There’s nothing stopping you from declaring the lazy views directly:

let r = 1...500
let l = LazyBidirectionalCollection(r)
let evens = l.filter { $0%2 == 0 }

But if you were implementing your own set of classes generated by this generic factory pattern, you could also put common set-up code in your generic factory method (or even have a generic factory class if needed).

Stride aside

By the way, the new stride function in beta 4 follows a similar pattern of returning different types at compile time from an overloaded function. But in its case, the overloading isn’t done by what you pass in. It isn’t done by types at all.

func stride<T: Strideable>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T>
func stride<T: Strideable>(from start: T, through end: T, by stride: T.Stride) -> StrideThrough<T>

These two functions differ only by the name of their middle parameter. I don’t know about you, but that this was possible was an eye opener. Score one for the Objective-C named arguments enthusiasts.

Extending lazy

So what if you have your own idea for a lazily evaluated filter to apply to sequences or collections? Well, you could extend the lazy classes to support it. We’ll look at that in the next article. Follow @airspeedswift to catch it.


  1. Which, frankly, was a bit smug of me. 
  2. Which, in this authors opinion, means they should kill the Array members map and filter, since they’re now duplicative. They could still be special-cased for performance purposes. 
  3. This behaviour can also be used to pick an optimized version of a collection algorithm that takes advantage of random access e.g. to find a subsequence inside a collection. 

Changes in the Swift Standard Library in Beta 4

Other than access control,1 no big changes to the language with Beta 4, unlike with Beta 3. But still plenty of changes to the standard library.

Some small bits and pieces:

  • Float and Double are no longer random access indices. Who was planning on indexing a collection with a Double, anyway? Just how big was your collection going to be?2
  • uppercaseString and lowercaseString properties are gone from String. I never liked them. Call a function a function, that’s what I say.
  • insertionSort and quickSort are gone. Generic non-name brand sorts only from now on.
  • Instead of having static members for true and false, Bool now implements the new BooleanLiteralConvertible protocol
  • CString is gone. You can still construct strings from c-style strings, but those now take a ConstUnsafePointer. Probably to discourage people from keeping the nasty little things hanging around in their native primordial form.
  • remainderWithOverflow replaces modulusWithOverflow
  • Yet more types are reflectable, and there’s now an enum value to represent Objective-C objects separate from Swift ones.

Now the bigger changes…

ArrayBuffer, ArrayBufferType, SliceBuffer and ContiguousArrayBuffer are gone. It was kinda surprising they were there in the first place, revealing the inner workings of Array. Sorry if you spent some time figuring out how to use them, but you probably had no business poking around in there. As a result, the makeUniqe member functions are also gone.

reverse is no longer lazy. It now gives you back an Array. Huh. Looks like if you really want to reverse something lazily, you now need to create a LazyBidirectionalCollection via a call to lazy(), then call .reverse() on it to get another lazy collection. Bit cumbersome, but probably more explicit.

There’s also LazyForwardCollection, LazyRandomAccessCollection, and LazySequence. lazy() will return the appropriate one from your base collection or sequence. All of them give a base the ability to map and filter, plus conversion to an array. Only the bidirectional and random ones can be reversed, obvs. And the random access one has a subscript. I guess I need to update my article on lazy collections and sequences.

Range is no longer sliceable. I don’t really “get” sliceable, but what I do get suggests Range shouldn’t have been sliceable.

Speaking of ranges, were you trying to use Range with floating-point types? Well cut that out and use StrideTo and StrideThrough instead, both created with a call to stride (with either a to or a through as the second argument name). They mirror respectively a half-open and closed version of Range. The big difference being if your stride length takes you past the end, they stop striding.

The version of filter that took a collection not a sequence is gone. It was a bit pointless anyway, since you can’t index randomly into a filtered collection without doing all the filtering up to that point. And the sequence version is no longer lazy, it returns an Array. If you want to filter lazily, use the explicitly lazy stuff above. If you want to filter starting from the back, you can do lazy().reverse().filter()

As ever, I refrain from commenting on anything relating to Unicode and Objective-C bridging, for fear of demonstrating my ignorance.


  1. About which I appear to be out of the mainstream in not being desperate for. I mean it’s important before go-live, sure. But some people seem to need a cold shower after hearing it’s in this beta. 
  2. Or how small! No, wait… 

Jumping to conclusions

In an article yesterday, I mentioned that I wasn’t having much luck extending Dictionary to give it an initializer that took a sequence of tuples, because my attempt wasn’t compiling, even though I was sure that it should:

extension Dictionary {
    init<S: Sequence
      where S.GeneratorType.Element == Element>
      (_ seq: S) {
        self.init()
        for (k,v) in seq {
          self[k] = v
        }
     }
}

Looked like the problem was with destructuring a typealiased tuple type into its consitutents. Like a good little beta tester, I settled in this morning with a fresh pot of coffee to file a bug report. My plan was to reproduce the problem without the Dictionary part, to try and clarify exactly where the issue lay. I tried writing a couple of classes that used typealiased tuples, one taking two generic placeholders and typealiasing the pair of them as a tuple, and then writing a function on one that took the other.

After about 20 minutes plugging away at this, I was still unable to reproduce it independently, and was geting quite frustrated. Then I realized hang on, what made me so sure this was a problem with tuples?1 I pushed aside my failed attempt and just tried compiling this, and got the exact same error:

extension Array {
    func someFunc<S: Sequence
      where S.GeneratorType.Element == Element>
      (_ seq: S) {
        for e in seq {

        }
     }
}

Well, shit. That’ll teach me to overthink a problem. I scold myself for not applying Occam’s razor and assuming the cause was more complicated than it was.2 Once I stopped obsessing over the tuple part, the next step in fixing my code became obvious. for ... in is just shorthand for creating a generator and then looping while next() returns non-nil elements. So I tried this:

extension Array {
    func someFunc<S: Sequence
      where S.GeneratorType.Element == Element>
      (seq: S) {
        var gen = seq.generate()
        let elem = gen.next()
    }
}

Bingo! The call to gen.next() reports Cannot convert the expression's type 'Self.Element? to type 'Self.Element?'. Somehow type inference is borked. But if I qualify the declaration of elem as elem: Element? it works fine.

So now I know how to work around it, I can finally write my sequence initializer for dictionary.

But first: @rbrockerhoff replied yesterday with a gist that was very close to the Sequence initializer (it took MapCollectionView as an argument rather than the sequence directly, which somehow avoids the type inference issue in a similar same way that my version that took an Array did).

As part of this, he did something very smart, which is to separate out inserting the sequence into the dictionary into another method, and then calling it from init instead of having the loop in init itself. This is a great example of solving something generically first, and then specializing your generic solution to the immediate problem. So here’s the full solution:

extension Dictionary {
    init<S: Sequence
      where S.GeneratorType.Element == Element>
      (_ seq: S) {
        self.init()
        self.merge(seq)
    }

    mutating func merge<S: Sequence
      where S.GeneratorType.Element == Element>
      (seq: S) {
        var gen = seq.generate()
        while let (k: KeyType, v: ValueType) = gen.next() {
            self[k] = v
        }
    }
}

let pairs = enumerate(["zero","one", "two"])
let d: [Int:String] = Dictionary(pairs)
d[1] // returns {Some "one"}... yes!

Just one wrinkle – you still have to give the dictionary variable a type, it won’t infer it. I’m not sure if this is a bug in my code, a Swift bug, or a feature not a bug. If you know, let me know.


  1. I was possibly nudged towards the tuple assumption because of another bug in playgrounds with mapping arrays of tuples. 
  2. I did the same thing yesterday when I convinced myself the only way to write my own Dictionary.init() was to create another dictionary and assign it to self, before a helpful comment from @NachoSoto suggested I just try self.init(). Duh. 

On dictionaries and initializers, in which I give up and use a for loop

On twitter, @rob_rix confessed that he’d given up and used a for loop. @rbrockerhoff replied he had too, in his case because you can’t create a dictionary from an array.

That tweet sent me deep down the rabbit hole experimenting with Dictionary. I keep wanting to fix it, like a scruffy boyfriend. But like with said boyfriend, that’s easier said than done.

Warning: some of the below is very experimental, thoroughly likely to crash your playground, and quite possibly wrongheaded in lots of places. If you spot any of the latter, do tweet me a correction @airspeedswift.

The root of the problem is that, unlike Array, Dictionary doesn’t have an initializer that takes a Sequence of key/value tuples. If it did, you could do cool stuff like this:

let words = ["zero", "one","two"]
let enumerated = enumerate(words)
let number_to_word = Dictionary(enumerated)
// results in [0:"zero", 1:"one", 2:"two"]

let d = [0:"zero", 1:"one", 2:"two"]
let flipped = Dictionary(Zip2(d.values, d.keys))
// results in ["zero":0, "one":1, "two":2]

Now, if you root around in the standard library1 you’ll find it does have this function, which it implements as part of the DictionaryLiteralConvertible protocol:

static func convertFromDictionaryLiteral
  (elements: (KeyType, ValueType)...) 
  -> [KeyType : ValueType]

This is tantalizingly close to what we want, at least for arrays if not sequences. It takes a variadic argument of tuples, which will in the function itself be represented as an array of tuples. Hey, we want to create a dictionary from an array of tuples! Can we use this?

Nope. Try as you might, you can’t shove an array through that function. If you managed to get one in, inside the function it would appear as an array inside an array. Languages like Ruby and Python have the ability to “splat” an array into a function as its parameters, but (as far as I can tell) there’s no way to do that in Swift.

Sigh. I guess there’s no alternative but to use a loop. But to make myself feel better about it, I’ll fix something else that bugs me about Dictionary. As we saw, convertFromDictionaryLiteral takes an array of (Key, Value) tuples. But the one function in Dictionary that also takes a key and a value takes them the other way around:

func updateValue(value: ValueType, forKey key: KeyType) -> ValueType?

You know how I said you can’t pass an array into a variadic argument in Swift? Well, you can pass a tuple into a function that has the same number of arguments as the tuple:

func takeTwoArgs(arg1: Int, arg2: String) {
//  do stuff with arg1 and arg2
}

let pair = (1, "one")
takeTwoArgs(pair)

To take an array of tuples and insert them into a dictionary would be a lot nicer if you could just pass the elements of the array in directly, rather than having to flip them around. This will do it:

extension Dictionary {
    // offensive vague naming of a function alert...
    mutating func update
      (key: KeyType, _ val: ValueType) 
      -> ValueType? {
        return self.updateValue(val, forKey: key)
    }
}

let pairs = [(0,"zero"), (1,"one"), (2,"two")]
var d: [Int:String] = [:]
for pair in pairs {
  d.update(pair)
}

OK, doing that makes me feel a bit more cheerful, but I’d still like to be able to construct a dictionary from scratch using an initializer. This isn’t just a whim, by the way – having to do the for loop above forces you to declare d with var, whereas an initializer could be used with let.

So how about we extend Dictionary with an initializer:

extension Dictionary {
  init(_ array: [Element]) {
    for pair in array {
      self.update(pair)
    }
  }
}

Oops, a mysterious compiler error. “Variable 'self._variantStorage' used before being initialized“. We’ve accidentally been exposed to the inner implementation of Dictionary. And unlike Array, which has some hints at how you might manipulate the underlying store with structs like ArrayBuffer, Dictionary is entirely enigmatic. We could try and figure out how to initialize _variantStorage by hand but that’s just going to lead to tears.

Or, we could just create another Dictionary, populate it, and then assign it to self right at the end of the initializer:

edit: Ignacio in the comments points out the (now blindingly obvious) alternative of just calling self.init() instead – thanks! But I leave the self-assignment here as something of interest that works.

edit edit: Maybe not so fast. self.init() works in playground, but not in compiled code right now.

extension Dictionary {
    init(_ array: [Element]) {
        var d: [KeyType:ValueType] = [:]
        for pair in array {
            d.update(pair)
        }
        self = d
    }
}

I have no idea if this is supposed to be allowed or not. I mean, it seems to work fine, but I think I might have voided the warranty. Certainly I’m going to think twice about filing this code as part of a radar.

Nevertheless, we can now do this:

let pairs = [(0,"zero"), (1,"one"), (2,"two")]
let d = Dictionary(pairs) // woo-hoo
// d now contains [0:"zero", 1:"one", 2:"two"]

For my last trick, I would love to say I’ve generalized this to work for sequences, but unfortunately I still can’t figure that one out. This seems like it ought to be the solution:

extension Dictionary {
    init<S: Sequence
      where S.GeneratorType.Element == Element>
      (_ seq: S) {
        var d = [KeyType:ValueType] = [:]
        for pair in seq {
            d.update(pair)
        }
        self = d
    }
}

but it segfaults the compiler (I need to find a way to reproduce this without the dodgy self-assignment, so I can file a radar with less silly code…) (edit: well, now I know a way! Was hoping that would fix the segfault, but no)

As a workaround, I’ve tried creating an array with the sequence and then using the previous initializer:

extension Dictionary {
    init<S: Sequence
        where S.GeneratorType.Element == Element>
        (_ seq: S) {
            var d = Dictionary(Array(seq))
            self = d
    }
}

However, this leads to the compiler compliaining that “'WhateverYourSequenceTypeIs' is not convertible to '[(KeyType, ValueType)]'“. This suggests it’s not matching the sequence initializer. If anyone can spot what’s wrong here and has a fix, let me know. For now, just stick an Array() around your init arguments and pretend you’re in for-loop free nirvana.

edit: found it! Read the next post for a solution.


  1. In case you don’t know how to do that, type import Swift into a playground then command-click on the word Swift. 

A better way to hit bottom

After my previous post on finding minimums, a couple of people pointed out that reduce would be much better suited to the task. They’re absolutely right, but I ignored that for the last post since I had another agenda. Plus, the combination of min and reduce is an interesting one with its own wrinkles, that deserves a post of its own, so here it is.

reduce takes a sequence, a starting value, and a combining function, and uses that function to boil the sequence down to a single value. For example, to total up the values in an array:

let a = [2, 4, 6, 8]
// starting with 0, add each value
// of 'a' to a running total
let sum = reduce(a, 0, +)
// sum = 20

That certainly sounds like what we want for finding the minimum value in a sequence, with min as the combining function (as recently made possible in beta 3):

let a = [5, 4, 3, 8]
// but what to put in the starting value?
let the_min = reduce(a, ???, min)

We need to pick a starting value to use on the first call to min. Unlike with addition, there’s no natural constant to start a search for a minmum value. You could start with the maximum value for an Int, but that smells like a hack.

Using the first element of the sequence would do it:

var gen = a.generate()
if let first = gen.next() {
    reduce(a, first, min)
}

But this means the first thing this code does every time is redundantly compare the first element to itself. Strictly speaking, that’s fine from a functional behaviour point of view, and even the performance consequences amortize to negligible, but it’s not very satisfying.

This version avoids that problem:

var gen = a.generate()
if let first = gen.next() {
    reduce(gen, first, min)
}

Why does that work? Because Array.GeneratorType happens to be both a Generator and a Sequence. In fact, in a quick scan through the Swift standard library, I couldn’t spot any generator that wasn’t also a sequence. But just because they always are doesn’t mean they have to be, which is why implementing a generic function tail that returns all but the first element of a sequence is surprisingly tricky – but let’s leave that for a later post.

So, armed with our ability to use reduce to find a minimum, let’s implement our solution from the previous post that finds the minimum numeric value in an array of strings:

let string_ints = ["dog", "12", "cat", "4", "200", "elephant"]

var gen = string_ints.generate()
if let first = gen.next() {
    reduce(gen, first) { (lhs, rhs) in
        switch (lhs.toInt(), rhs.toInt()) {
        case (_, nil): return lhs
        case (nil, _): return rhs
        case (let i, let j): return i < j ? lhs : rhs
        }
    }
}

OK that works, but this is pretty ugly with the generator on top of that convoluted closure. And remember last time I mentioned there were still a couple of issues – if string_ints contains no integer strings, it’ll just return the first non-integer string. And it does every integer conversion twice.

Do we still need the generator? Our closure that chooses between sequence elements now discards nil values as soon as it finds a non-nil one. That means that we could supply nil as our initial argument. This also means a returned value of nil could stand in for “not found”, either because the sequence was empty, or because it contained no strings convertible to numbers.

But before we make that change, let’s neaten things up by pulling out the code that does the nil discrimination into its own function.

Here is combineMaybe, a function that takes a function that combines two values (like min), and returns a new function that chooses between two optionals, always preferring the non-nil one before resorting to the supplied function if neither value is nil:1 2

func combineMaybe<T>
  ( combine: (T,T)->T ) 
  -> (T?,T?)->T? {
    return { lhs, rhs in
        switch(lhs, rhs) {
        case (_, nil): return lhs
        case (nil, _): return rhs
        default: return combine(lhs!,rhs!)
        }
    }
}

combineMaybe is a function decorator – a function that takes another function, and enhances it in some useful way, returning the enhanced function.

We can now use the standard library version of min, enhanced with our decorator, as the combiner function to reduce, supplying nil as the starting value. An initial call to map to first convert the strings to integers generates the input sequence:

let string_ints = ["dog", "12", "cat", "4", "200", "elephant"]
let maybe_ints = map(string_ints) { $0.toInt() }

if let the_min = reduce( maybe_ints, nil, combineMaybe(min)) {
    // the_min = 4
}
else {
    // handle both empty input or no numerics in input
}

This fixes the bug of returning a non-numeric string when that’s all the sequence contains. And it only converts each number once, in the call to map.3 4

If instead we wanted to pull out the maximum values, all that is needed is to replace the passing of min into combineMaybe with max, with everything else remaining the same.

In fact, it’ll even work with other binary functions as well. If you replaced min with +, it’ll add all the numeric values in the array, while still giving you a chance to catch if no numbers were found in the sequence (sometimes zero is still not the right answer for an empty sequence, even one containing integers rather than strings).


  1. The “maybe”-based name comes from Haskell, where maybe is a function that takes a default value, a function, and an optional type (which are called Maybe types). 
  2. As ever, really wishing switch was an expression that returned the value of its cases when they were single expressions. 
  3. Ok, so this doesn’t fulfil the original requirement of returning a string rather than an integer (from the previous article). I think we can keep that as a subsequent step, I was mostly being antagonistic about that part. 
  4. Haskell also has a function, mapMaybe, that is like a map to an optional value, followed by a filter that removes all the resulting nil values. That would be a good building block for solving this problem too, though it still wouldn’t help with the starting value for reduce. 

Swift Structs and accessing properties by name

Brent Simmons posted a blog article today about a feature he was missing from Swift that was readily available in Objective-C – the ability to access properties of an object indirectly using a string.

Brent’s goal is to be able to write some generic code that compares various different properties. Here’s how he puts it:1

For every merge-able property there are really two properties, and there’s a simple naming convention.

For example, a note’s archived flag has two properties: archived and archivedModificationDate.

Merging works like this pseudo-code:

if existingObject.archivedModificationDate < serverObject.archivedModificationDate {
existingObject.archived = serverObject.archived
existingObject.archivedModificationDate = serverObject.archivedModificationDate
}

But the code doesn’t actually look like that. Instead of duplicating the above for each property, there’s a single method that takes server object, existing object, and property name as parameters. Then it uses valueForKey: on both server object and existing object. (It gets the key for the date value by adding “ModificationDate” to the property name.)

This turns merging a given property into a one-liner:

mergeProperty(existingObject, serverObject, “archived”)

He asks if there’s a way to do this right now. The answer is almost, with some shortcomings (most of which will hopefully get resolved before the end of the beta).

Firstly, here’s an example version of a struct with some properties:

(I’m using Int as a stand-in for a date/time object, for simplicity)

struct Properties {
    // someday soon these can be private
    var _name: String, _nameModificationDate: Int
    var _shape: String, _shapeModificationDate: Int

    init(name: String, nameModificationDate: Int,
         shape: String, shapeModificationDate: Int) {
            self._name = name
            self._nameModificationDate = nameModificationDate
            self._shape = shape
            self._shapeModificationDate = shapeModificationDate
    }

    func name()->String { return _name }
    func nameModificationDate()->Int { return _nameModificationDate }

    func shape()->String { return _shape }
    func shapeModificationDate()->Int { return _shapeModificationDate }
}

Note that the “getter” methods for name and shape are methods, not var properties with a { get }. This will be important later.

This struct is both immutable in the sense that there are no setter methods, and also can be immutable because it’s a struct you can declare with let instead of var. There’s an important distinction here – classes can be immutable too, in the former sense. A pattern in the Swift standard library is to declare an immutable version of a protocol that only has read methods (such as Collection, that declares an rvalue version of subscript), and then an inherited version that is mutable and has write methods (such as MutableCollection, that declares an lvalue version of subscript).

Of course, right now there’s no private variables in Swift, so internal variables are still writeable, but Apple have made it pretty clear this is coming in a later beta.

Having declared our struct, we create a dictionary that can be used to access the getter methods:

let propertyDict = [
    "Name":  (Properties.name, Properties.nameModificationDate),
    "Shape": (Properties.shape, Properties.shapeModificationDate),
]

This dictionary maps a string name onto a tuple containing two member function references,2 one for the property and one for its associated modification date. They have a type of Properties->()->String (or ->Int ). You use them first by applying an instance of the object, which returns a new function bound to that instance, and then calling the function.

Here is why the accessors had to be methods. To my knowledge, you can’t do the same thing with var propertyName { get } properties, for the simple reason they don’t need () to invoke, so you can’t leave it off to get the method reference. Maybe under the hood there’s a secret get_propertyName() function you could use, but I can’t find it.

To demonstrate these in use, here’s the implementation of the mergeProperty function:

func mergeProperty(existingObject: Properties,
    serverObject: Properties,
    propertyName: String) 
    -> (String, Int) {

        // fetch the property-accessing member function references
        // associated with propertyName
        if let (property, propModDate) = propertyDict[propertyName] {

            // now get the modification date for this property
            // for both the existing and server versions
            let existingModDate = propModDate(existingObject)()
            let serverModDate = propModDate(serverObject)()

            // do your date comparison to pick the winner
            if existingModDate >= serverModDate {
                return (property(existingObject)(), existingModDate)
            }
            else {
                return (property(serverObject)(), serverModDate)
            }
        }
        else {
          // throw an exception! (only kidding, in practice mergeProperty's 
          // return type should probably be optional and return nil to 
          // account for this possibility
          return ("",0)
        }
}

And here is the mergeProperty function in use:

let existingObj = Properties(name: "Fred", nameModificationDate: 10,
    shape: "Square", shapeModificationDate: 20)

let serverObj = Properties(name: "Bob", nameModificationDate: 12,
    shape: "Circle", shapeModificationDate: 18)


let (mergedName, _) = mergeProperty(existingObj, serverObj, "Name")
let (mergedShape, _) = mergeProperty(existingObj, serverObj, "Shape")

// mergedName = Bob, and mergedShape = Square

There are a lot of likely objections to the above code, some of which can be addressed by more code, some by possibly-upcoming Swift enhancements, and some that are just fundamental to Swift.

The hardcoding of the entries in propertyDict. This is the inevitable result of there being no official reflection in Swift. Yet. There’s clearly the beginnings of reflection with the getMirror() method and AnyClass type. I’d be surprised if Swift made it all the way through beta without it being added. Once there’s reflection, you could build up propertyDict at runtime (and also hopefully compile time if you prefer) based on a list of property names and a naming convention.

Jason Peebles tweeted an alternative, that involves access to the raw member variables using the nascent reflection capabilities. This is very interesting, and kind of like solving this from the other end. My concerns with this approach is it feels better to me to use methods, though maybe that’s my own prejudice. Also, that current reflection API is possibly temporary and only there to facilitate the playground and debugger. Eventually when full reflection is implemented, hopefully both methods and member variables will be exposed (maybe they are already with a bit more playground spelunking).

It only supports strings. In real-world use, you would wrap up propertyDict and mergeProperty together into a class (along with the reflection that took the metaclass and a list of property names), which you could then make generic to operate on Int or String accessors depending on need.

Use of methods instead of properties. I don’t know how to fix this right now. Leave a comment if you do! But for the most part, anything you can do with properties you can also do with getting and setting methods, so it’s not a deal-breaker.3 This is the biggest sticking point though.

It’s not how it works in Objective-C. More of a philosophical difference, this one. But you could probably reproduce nearly all the behaviour of valueForKey using the above technique. The solution using generics is still going to leave you fighting the type system a bit more than you might in Objective-C, and while using Any instead might get you closer, I usually find myself fighting even harder with Any than I did with types.

An implementation that is true to the valueForKey behaviour, by which any property can be fetched with a single method call, seems by definition to require a return of an Any variable which gives up much of the type safety Swift is forcing you towards. Maybe whatever reflection solution eventually emerges will show a pleasing middle-ground.

Anyway, hopefully this solves at least part of Brent’s problem. Maybe some day some of this code will make it into Vesper, which would be very exciting as I’m a big fan of the app.


  1. Sorry about butchering the code part. My blog engine and I are not getting along. 
  2. I made that term for them up, by the way. It’s not like an official name for them or anything. It’s what they’re called in C++, which Swift seems to model in this respect. 
  3. At least until Apple implements KVO in Swift only for properties. Then this technique is screwed. 

Always write a generalized version of your algorithm

Suppose you want to find the minimum value in an array. Well, the Swift standard library has you covered:

let a = [6, 2, 4, 7, 8, 10]
minElement(a)  // returns 2

Ok that’s cool. But suppose you have an array of strings of integers and you want the minimum numeric value.

Well, I guess you could map them to Int and then use the same function:

let a = ["6", "2", "4", "7", "8", "10"]
minElement( a.map { $0.toInt() })

Nope, compiler error. String.toInt returns an Int?, because maybe the string isn’t a number.

Fair enough. I happen to know with my intimate knowledge of the problem domain that we can just ignore non-numeric values. So maybe filter those out?

minElement( a.map { $0.toInt() }.filter { $0 != nil } )  // hmmm

Nope, more compiler errors, because now we have only non-nil values, but they’re still optionals and an Int? doesn’t conform to Comparable. So maybe another map to force-unwrap the results (force unwrap is OK because the filter will guarantee no non-nil elements):1

minElement( a.map{ $0.toInt() }.filter { $0 != nil }.map { $0! } )  // yuck

Ok that compiles now and does return the minimum numeric value. But what if we wanted the result to still be a string?

"\(minElement( a.map{ $0.toInt() }.filter { $0 != nil }.map { $0! } ))" // bleurgh

That’s pretty horrible, and at this point I’m thinking of registering GiveUpAndUseAforLoop.com,2 and Marco Arment is yelling at you kids with your new language to get off his lawn.

Really, what we need is for minElement to take a predicate instead of only using the default <. It doesn't (mutter, grumble) but if it did, we could write this:

minElement(a) {
    switch ($0.toInt(), $1.toInt()) {
    case (_, nil): return true
    case (nil, _): return false
    case (let i, let j): return i < j
    }
}

Ahh. Faith in the functional programming style restored.3 This takes each element, checks if the toInt() of either is nil using pattern matching, always preferring the non-nil version, and if neither are, compares them. Since all it's doing is comparing the converted value, not returning one, the minimum returned is a string.4

There's nothing stopping you from implementing your own overload of Apple's minElement that takes a predicate:5

func minElement
  <E, R: Sequence
  where E == R.GeneratorType.Element>
  (range: R, pred: (E,E)->Bool) -> E {

    var gen = range.generate()
    var min_so_far = gen.next()!

    while let next = gen.next() {
        if(pred(next,min_so_far)) {
            min_so_far = next
        }
    }

    return min_so_far
}

This version copies the Swift library version's questionable practice of exploding in flames if you pass it an empty sequence – the (better?) alternative being make the return value optional to force the caller to acknowledge this possibility.

The moral here is that if you ever write a high-order function, write it as generally as possible. It's only a few extra lines to declare the common case using the general case:6

func minElement
  <E: Comparable, R: Sequence
  where E == R.GeneratorType.Element>
  (range: R) -> E {
    return myMinElement(range, <)
}

Apple does this for most functions (such as sort), just not minElement. But then it is only beta 3, hang in there.


  1. “I thought it was guaranteed not to be nil at this point” is what you could write to the log file in the outer exception handler you can’t have. 
  2. Just kidding, I didn’t think about it, I registered it straight away. 
  3. This code would be even neater if the Swift switch statement would implicitly return the values of single-line cases, i.e. if all the returns in that closure were removed, the switch would evaluate to the value of the selected case statement, and the closure would return it. They closed my radar as a dupe of 16169366 (don't file another duplicate though). 
  4. It's still not perfect – if none of the elements are numeric, it'll return the first one. Also, it'll convert each element twice. Hold that thought for a later post though. 
  5. Actually, there might be some compiler bugs stopping you, but I'll leave you to discover those on your own. 
  6. If the language would let you, you could even default the last parameter to <, but it won't, so you can't. More dynamic default arguments (including ones derived from other arguments to the same function) could be pretty useful in cutting down the amount of code you need to write for these general- and special-case versions.