Swift: Six Killer Features

Screen Shot 2015-05-21 at 9.03.12 AM

There’s a lot to love about Swift. Here are 6 of my faves.

1. Stride

Swift’s stride function returns a sequence of values of any “strideable” type. Strideable types are one-dimensional scalars that you can offset at set distances. So if you want to build a floating point sequence between, say, 0.0 and 8π, you just stride to create values and then map to apply a function to them.

let π = Double(M_PI)
let max = 8.0 * π
let damp = map(
     stride(from:0.0, to:max, by:π / 6.0))
     {1 - cos($0) * exp(-(2.0 * $0 / max))}

Stride offers two variants. The to form used here creates this sequence:

start, start + stride, start + 2 * stride…start + n * stride

The last item (start + n * stride) is strictly less than the maximum value.  In its through form, the last value is less than or equal to the maximum value.

These more or less correspond to open ranges and closed ranges. Unlike closed ranges, the math doesn’t guarantee that the through version ever actually reaches the end value. The elements in

stride(from:0.0, through: 1.0, by: 0.3)

are 0.0, 0.3, 0.6, 0.9. The next number would be 1.2. This is bigger than 1.0, so the sequence stops.

The stride function is perfect for mapping. When used in a playground (as you see in the screen-shot at the top of this post), it establishes beautifully graph-able output.

2. GeneratorOf

Create quick and dirty lazy sequences with just a line or two of code using GeneratorOf. For example, the following generator outputs a sequence of natural numbers:

var n = 0
var naturalNumbers = GeneratorOf{n++}

Each time you call next(), it outputs a new value.

naturalNumbers.next() // 0
naturalNumbers.next() // 1
naturalNumbers.next() // 2

A little tweak adjusts this to produce just even numbers:

var evenCount = 0
var evensGenerator = GeneratorOf{evenCount++ * 2}

Or a Fibonacci sequence:

var fibs = ArraySlice([1, 1])
var fibGenerator = GeneratorOf{
    _ -> Int? in
    fibs.append(fibs.reduce(0, combine:+))
    return fibs.removeAtIndex(0)
}

Mike Ash offers a delightful one-line Fibonacci alternative here.

3. Split

Perfect for decomposing strings and other sequences, add a closure that determines where to split any sliceable type:

let lipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
let words = split(lipsum, isSeparator:{$0 == " "}) // ["Lorem", "ipsum", ...]

4. Lazy

Return a sequence or collection type that’s ready for filtering and mapping without producing an intermediate array. Use this for items where you’re just going to feed the results into another processing step.

let counts = lazy(words).map(count)

5. Zip

Zip create pairs from sequences. Pass in two arguments, it returns a  Zip2([T], [U]) sequence, ready for mapping or filtering.

map(zip(words, counts)){println("\($0): \($1)")} // Lorem : 5, ipsum : 5, ...

Zip items into array pairs by mapping:

let array = map(zip(a, b)){[$0, $1]}

6. Format Strings

Format strings aren’t just for Foundation. Build your own. No NSString required!

String(format: "Value: %3.2f\tResult: %3.2f", arguments: [2.7, 99.8])

The following initializer enables you to skip brackets:

String.init(format: String, _ arguments: CVarArgType...)

so all you need to type is:

String(format:"Value: %3.2f\tResult: %3.2f", 2.7, 99.8)

Like the write-up? Please check out my playgrounds book!

p.s. Thanks to Mike Ash and Kevin Ballard for input

6 Comments

  • Awesome, thanks! Not sure how I missed (or forgot about) split, but it’s in the wheelhouse now thanks to this write-up. And the fibonacci generator will definitely come in handy in my app LŌC

  • Superb…

  • can’t wait for the next one… Nice and brief.

  • Thank you. I didn’t was aware of the stride() function

  • tried 1. and got : expression was too complex to be solved in reasonable time…..?!