So I’m waiting for Xcode to eventually download because I actually need to *use* it in my real life. Everything has come to a screaming halt because it’s dinner time and because of this:

and this:

So instead, I have some notes sitting around while I make dinner. I can’t guarantee any of them make any sense whatsoever (since I can’t open Xcode to test) but I thought I’d just throw them out there and see if they connect with anyone out there in the land of electrons beyond my screen. It may be useful. It may be crap.

Looping through a sequence of integers:

for index in 0..<n {...}

Looping with a where clause:

for index in 0..<n where n % 2 == 0 { }

Looping with map:

for index in (1..<n).map({ $0 * 10 }){ } // 10 to n-ty
for index in (1..<n).map({ pow(2.0, Double($0) }){ } // 2^idx

Theoretically you could adjust “stride” to take a function but you *really* don’t want to. If you’re using value(n+1) = f(value(n)) *it’s not a stride*. It’s something something non-stride. I call it stride here because whoever I was talking with was all “couldn’t stride take a closure”? and I was all “yeah, sure”:

func stride(from value: Int, to cutoff: Int, by f: (Int) -> Int) -> AnySequence<Int> {
var current = value
return AnySequence {
return anyGenerator {
guard current <= cutoff else {return nil}
defer {current = f(current)}
return current
}
}
}

The closures aren’t particularly self-documenting or readable. And don’t try to produce side-effects in the `by`

closure. That’s just wrong.

for i in stride(from: 1, to: 10, by: {$0 + 1}) // ++
for i in stride(from: 1, to: 1_000_000, by: {$0 << 1}) // shift
for i in stride(from: 1, to: 200, by: {$0 * 2 + 1}) // 2x + 1

Some traditionalists want to directly affect an index, not just supply the RHS of an assignment. The second you introduce `inout`

, the clarity and readability plummet from an already not-very-great situation.

func stride(from value: Int, to cutoff: Int, by f: (inout Int) -> Void) -> AnySequence<Int> {
var current = value
return AnySequence {
return anyGenerator {
guard current <= cutoff else {return nil}
defer {f(¤t)}
return current
}
}
}
for i in stride(from: 1, to: 10, by: { (inout idx: Int) in idx += 1 }) {}
for i in stride(from: 1, to: 1_000_000, by: { (inout idx: Int) in idx = idx << 1 }) {} // shift
for i in stride(from: 1, to: 200, by: { (inout idx: Int) in idx = idx * 2 + 1 }) {} // 2x + 1

No floating point stuff here because floating point is broken. If you really need it, well you could do worse than this for stuff like iterating by `M_PI/30`

at a time around a circle or looping from 0.0 to 1.0 by 0.1.

func stride(from value: Double, to cutoff: Double, byOffset offset: Double) -> AnySequence<Double> {
var count = 0 // Int
return AnySequence {
return anyGenerator {
let current = value + Double(count) * offset
guard current <= cutoff else {return nil}
defer {count += 1}
return current
}
}
}