Jive with Beta Five #swiftlang

Some highlights of the new beta.

Really, Apple? I need Xcode 7 Beta 5 to be Xcode6-Beta for the sake of my shortcuts. Xcode hates when you change its name but I don’t want to start messing with my Keyboard Maestro macros right now. Seriously, had to go through five separate launch cycles before it took.

Screen Shot 2015-08-06 at 12.03.03 PM

ErrorTypes for Everyone! Remember this workaround for non-Enum ErrorType instances? No longer an issue starting with Beta 5 and later. Structs and classes are now allowed to conform to ErrorType. (21867608)

Here’s my revised code. It no longer requires the _domain and _code synthesis and it looks like Apple returns 1 for the code and the type name for the domain.

public struct Error: ErrorType {
    // No longer required
    //    public var _domain: String {return "com.sadun"}
    //    public var _code: Int {return 0}
    
    var reason: String
    var source: String
    
    // Initializer only requires a reason
    // The working inline macros are courtesy of Mike Ash
    public init(_ reason: String,
        source: String = __FUNCTION__,
        file: String = __FILE__,
        line: Int = __LINE__) {
            self.reason = reason
            self.source = "Thrown in \(source) (File: \(file) Line: \(line))"
    }
}
let e = Error("just because")
print(e._code) // 1
print(e._domain) // Error
let e2 = Error("it's thursday")
print(e2._code) // 1

Stoppable Playgrounds! Playgrounds can now be set to run manually or automatically when changes are made, as well as stopped during execution. (18058289) Yayayayayayayayay.

Screen Shot 2015-08-06 at 12.23.31 PM

Here’s where it really helps to have a keyboard binding for “Execute Playground”. Mine is F8. What’s yours?

ForEach: Just when I finally got around to implementing this generically:

public extension SequenceType {
    func mapDo(p: (Self.Generator.Element) -> Void) {
        for x in self {p(x)}
    }
}

Apple introduced forEach.

Array(1...5).map({$0 * 2}).forEach{print($0)}

You use this procedurally when you don’t collect/return the results. Notice how I’ve followed the Rule-of-Kevin-Ballard above. No parens around the braces because the closure is procedural.

public func forEach(@noescape body: (Self.Generator.Element) -> ())

This new language feature eliminates the awkward “for _ in” construct and provides a procedural end-point for functional chains. If you want to continue the chain (for example if you want to throw a print($0) in the middle) continue using map, which offers pass-through.

Apple’s pointers:

  • Unlike for-in loops, you can’t use break or continue to exit the current call of the body closure or skip subsequent calls.
  • Also unlike for-in loops, using return in the body closure will only exit from the current call to the closure, not any outer scope, and won’t skip subsequent calls.
  • Due to these limitations, the forEach member is only recommended when applied to a chained series of functional algorithms (e.g. foo.map {…}.filter {… }.forEach { …}) and when the body is small. In other cases, we recommend using the for..in statement. (18231840)

Pass through dictionary removal. Dictionary finally performs return instead of void on removeAtIndex:. This now matches behavior in arrays, and enables you to use each item that’s removed, splitting the dictionary into a kind of key/value version of head-tail.

4 Comments

  • […] Xcode 7 beta 5 and Swift […]

  • Apple made stringByAppendingPathComponent unavailable in the String class of Swift.

  • “Rule-of-Kevin-Ballard” Can I read more about that style?
    Why not removing “()” – Array(1…5).map{$0 * 2} .forEach{print($0)}

    • The rule is this: Parens around closures that return values, no parens around trailing procedural elements