Archive for the ‘Swift’ Category

Non-contiguous raw value enumerations

Brennan Stehling recently uncovered a fantastic Swift feature I was completely unaware of. I knew you could create raw value enumerations that automatically incremented the value for each case:

enum MyEnumeration: Int {
   case one = 1, two, three, four
}

MyEnumeration.three.rawValue // 3

And I knew you could create raw value enumerations with hand-set values:

enum MyEnumeration: Int {
    case one = 1, three = 3, five = 5
}

But I didn’t know that you could mix and match the two in the same declaration! (Although, you probably shouldn’t do this for standards-based values like the following example…)

enum HTTPStatusCode: Int {
    // 100 Informational
    case continue = 100
    case switchingProtocols
    case processing
    // 200 Success
    case OK = 200
    case created
    case accepted
    case nonAuthoritativeInformation
}

HTTPStatusCode.accepted.rawValue // 202

How cool is that?

I’d probably reserve this approach for values with offsets (for example, “start at 1”), and where the underlying values don’t have established semantics. As Kristina Thai points out, skipping meaningful values doesn’t help readability or inspection.

Pretty much every way to assign optionals

Store a non-optional or an optional to an optional

The basics. This isn’t rocket science:

optItem = 5 // optItem is now .some(5)
optItem = optValue // optItem is whatever optValue is

Summary

How often do you do this? All the time

How ridiculous is this approach? Not at all

Store an optional to a non-optional

Many functions and methods that return optional values. When you use try? with throwing, that returns optional values too.  You often need to store those results to a non-optional variable or property.

To do this, you test for nil and then store an unwrapped version of any non-nil results. Here are a few approaches.

Conditional Binding

Use if let to conditionally bind the optional and then perform the assignment:

if let optItem = optItem { 
    item = optItem // if optItem is non-nil
}

You can also use if case if you really want to although these do exactly the same things as if let:

// Sugared optional
if case let optItem? = optItem { 
    item = optItem // if optItem is non-nil
}

// External let
if case let .some(optItem) = optItem {
    item = optItem // if optItem is non-nil
}

// Internal let
if case .some(let optItem) = optItem { 
    item = optItem // if optItem is non-nil 
}

Nil Coalescing

You can use nil coalescing to provide a fallback value:

item = optItem ?? fallbackValue

If you don’t want a fallback value, you can use the item’s original value:

item = optItem ?? item

A slight caution. I don’t know if the compiler optimizes away the “assign self to self” case. If it has to do both the check and assignment,  this may be less efficient than the if let approach.

Also, I’m not giving this high marks for efficiency or readability because I think it’s worth the extra if let words to make clear the intent that you only update item if optItem is non-nil

Summary

How often do you do this? Often

How ridiculous is this approach? Not at all

Update optional only if optItem is non-nil

This variation describes a scenario where you skip updates when an existing optional is nil. In this case, nil means “don’t touch this optional”. I can count up to zero the number of times this scenario has ever arisen for me.

The obvious solution:

if optItem != nil { optItem = newValue }

The extremely weird solution using a ? marker:

optItem? = nonOptionalValue

In this use of ?, the rhs must be a non-optional, guaranteed at compile time. This is a pretty obscure Swift language feature. (Thanks to Joe Groff for reminding me it existed.)

Or you could do this (which is kind of silly) for “test for non-nil receiver” assignment:

if let optValue = optValue {
    optItem? = optValue
}

In this example, the rhs of the ?-powered assignment has to be non-optional. Conditionally binding the optional enables you to use it with ?. Madalin Sava offers the following simple alternative. It gets high marks for parsimony, low marks (as everything in this section does) for non-obvious outcomes:

optItem? = optValue ?? optItem!

 

Summary

How often do you do this? Never

How ridiculous is this approach? Extremely

Update optional only if optItem is nil

This variation can best be described as “set once, use mostly”. Once assigned to a non-nil value, the optional should never be overwritten. The simplest approach is to check for nil before assignment:

if optItem == nil { optItem = newValue }

Or burn an operator, which you probably won’t want to do:

infix operator =?? : AssignmentPrecedence

// "fill the nil" operator
public func =??<T>(target: inout T?, newValue: T?) {
    if target == nil { target = newValue }
}
optItem =?? newValue

See also: SE-0024

Summary

How often do you do this? I don’t do this but I can see the utility when hooking up assets that you don’t want to overwrite. This is kind of a mad-world version of implicitly unwrapped optionals but one where you test to ensure you’ll never change them again, not one (as with IUO’s) where every successive change has to be a non-nil value.

How ridiculous is this approach? Not ridiculous but also not common.

Update optional only if new value is non-nil

This scenario basically mimics implicitly unwrapped optionals but with added safety and no IUO crashing. You always test for non-nil so once set to a valid value the optional will never return to nil.

Limit updates to non-nil new values and discard nil assignments:

if let newValue = newValue { optItem = newValue }

Or this (which feels wasteful as it performs a re-assignment for nil-values, doesn’t it?):

optItem = newValue ?? optItem

or burn an operator, which again you probably won’t want to do:

infix operator =? : AssignmentPrecedence

// "assign non-nil values" operator
public func =?<T>(target: inout T, newValue: T?) {
    if let newValue = newValue {
        target = unwrapped
    }
}

See also: Swift Evolution.

Summary

How often do you do this? I don’t but I can see how people might want to use this with non-IUO optionals.

How ridiculous is this approach? Not ridiculous but also not common.


I’m sure I’ve gotten some of this write-upwrong. Tell me and I’ll fix.

Swift Idioms

Over time, Swift has developed a distinct dialect, a set of core idioms that distinguish it from other languages. Many new developers now arrive not just from Objective-C but also from Ruby, Java, Python, and more. The other day, I was helping Nicholas T Chambers find his groove with the new language. He was porting some Ruby code to build up his basic language skills. The code he was working with was this:

def find_common(collection)
    sorted = {}
    most = [0,0]

    for item in collection do
        if not sorted.key? item then
            sorted[item] = 0
        end

        sorted[item] += 1

        if most[1] < sorted[item] then
            most[0] = item
            most[1] = sorted[item]
        end
    end

    return most
end

And his most recent Swift attempt was this:

func find_common(items: [Int]) -> [Int] {
    var sorted = [Int: Int]()
    var most = [0, 0]

    for item in items {
        if sorted[item] == nil {
            sorted[item] = 0
        }

        sorted[item]! += 1

        if most[1] < sorted[item]! {
            most[0] = item
            most[1] = sorted[item]!
        }
    }

    return most
}

Other than a couple of forced unwraps, there’s almost no difference between the two.  I  don’t know much Ruby but this code in both versions feels very C-like and non-functional (in the fp sense, not the “won’t work” sense).

I know Ruby supports some kind of reduce functionality, which you don’t see here. One of the first things I did when trying to learn Swift was to implement pages and pages of Ruby functional calls. I still have endless select, reject, delete_if, keep_if, etc playgrounds around. They’re really great for focusing in on learning the Swift language.

Here’s the rewrite I suggested:

import Foundation

extension Array where Element: Hashable {
    /// Returns most popular member of the array
    ///
    /// - SeeAlso: https://en.wikipedia.org/wiki/Mode_(statistics)
    ///
    func mode() -> (item: Element?, count: Int) {
        let countedSet = NSCountedSet(array: self)
        let counts = countedSet.objectEnumerator()
            .map({ (item: $0 as? Element, count: countedSet.count(for: $0)) })
        return counts.reduce((item: nil, count: 0), {
            return ($0.count > $1.count) ? $0 : $1
        })
    }
    
}

In a way, this is an unfair refactor because I “went there” with NSCountedSet but writing in Swift doesn’t mean you reject Foundation. It seems to me that a counted set is exactly the kind of thing this code was trying to do: “Say you have a list of a random type (but its the same type throughout), in an arbitrary order. how do you find the most common item in the list?“.

Here are some thoughts about the refactor

Leverage Libraries. When migrating Swift, consider whether Foundation and Swift Foundation types will get you there faster. Counted sets provide a good match here because they do all the work of grouping and counting members. I wish there were a native version as I’m not crazy about either the object enumerator or that the code will compile even if you don’t specify hashable elements.

Embrace Generics. The challenge list uses a random type. Hardcoding Int isn’t the way to do that. Bring generics into the solution early once you recognize the functionality is applicable to many types.

Consider Protocols. A native version of counted set would be Hashable at a minimum, just like Swift sets.  I include the restriction here but it does compile and run without that conformance.

Live Functionally. Any kind of “find this within a list” screams functional programming to me. If your variables exist to store intermediate state while iterating a list, look to Swift’s core map/filter/reduce fp calls and eliminate explicit state.

Avoid Global Functions. I felt my implementation was better expressed as a collection extension than a freestanding function. A mode always describes and operates on an array. Its implementation belongs as part of Array. I even considered making it a property rather than a function because a list’s mode is an intrinsic quality of an array. I’m still wavering back and forth on that point.

Think Tests and Documentation. Even before you write a single line of code, considering test cases and documentation has become a core part of Swift development. I added a little doc markup here, I didn’t add any tests.

Prefer Good Swiftsmanship. At first, I was drawn to syntactic specifics, like “use conditional binding” and “type the variable/prefer a literal” before I stepped back and considered the larger picture. Once I took a few moments to think about it, I retargeted my advice towards fp, but that doesn’t mean core Swift best practices should be overlooked.

A lot of this falls into the big picture little picture dichotomy. When learning Swift, you probably want to work from the details up: learning how optionals work and how to use them right and how to use fp, all the way to creating tests, documentation, and leveraging protocols and generics. It’s hard to get hit in the face with so many concerns at once.

Adding core API knowledge on top of *that* makes things even more difficult. Navigating both utility types and Cocoa/Cocoa Touch APIs represent a significant challenge to those new to Apple platforms, even for people with strong backgrounds in modern language fundamentals.

At this point, writing “Swiftily” doesn’t just mean using conventional coding idioms but also remembering and leveraging the platform the language is arriving from. I hope counted set (and many other Cocoa Foundation outliers) make it over the bridge to native inclusion.

Safe Programming: Optionals and Hackintoshes

Here’s a doozy of an outlier case where conditional binding could  have saved a user experience for an otherwise unhappy consumer. I recently talked with a developer whose production code mixed forced unwraps with a guaranteed API. I wasn’t sure whether to tag this post as Holy War. As you’ll discover, this isn’t your run of the mill development situation.

The deployed-code crashes occurred while querying Apple’s smart battery interface on a Hackintosh. Since the laptop in question wasn’t an actual Apple platform, it used a simulated AppleSmartBatteryManager interface rather than the Real Thing™. In this case, the simulated manager didn’t publish the full suite of values normally guaranteed by the manager’s API.

The developer’s API-driven contract assumptions meant that forced unwraps broke his app for that user:

Since IOKit just gives you back dictionaries, a missing key, is well… not there, and nil. you know how well Swift likes nils…

Applications normally can’t plan for, anticipate, or provide workarounds for code running on unofficial platforms. There are too many unforeseen factors that cannot be incorporated into realistic code that ships.

Adopting a universal style of conditional binding enables you to “guide the landing” on unexpected failures, including those failures that occur under less exotic circumstances. Conditional binding lets you introduce a user-facing “bad stuff happened” alert, like the following example:

guard let value = dict[guaranteedKey] 
    else {
        alertUser("Functionality compromised when unwrapping " +
            "Apple Smart Battery Dictionary values. Skipping this " +
            "feature. Please file a bug with full platform info, etc..")
        return
}

Contrast the preceding “safe landing” approach with the more common approaches demonstrated in the following snippet:

// Crash, angry user, bad reviews
let value: String! = dict[guaranteedKey] // or
let value: String = dict[guaranteedKey]!

Prefer a style that establishes a positive pathway for both recovery and user support. Providing fallbacks and user-facing alerts even when your assumptions are guaranteed to be correct  is a always positive coding style.

Universal conditional binding reduces the overhead involved in  debugging unexpected Black Swan deployments and allows you to respond with “Sorry pal, my software is only guaranteed to work on official platforms. No refunds.” This practice  adds robustness and assumes that in reality bad execution can happen for the oddest of reasons.

Like my posts? Buy a book. Swift Style is available now via Pragmatic Programmer’s Beta Program.

Don’t attempt tech conversations after anesthesia

Does anyone know if I need to capture self as weak in a UIView.animation block?

Once I was afraid. I was petrified. Scared I couldn’t render without view at my side. Then I spent so many nights thinking how you did me wrong, and I referenced strong, and I learned how to pass my ARC along…

And now you’re back from @nonescape. I just walked in to find you here with that sad look upon your face.

I should have made you dereference, should have made you leave your key, if I’d known for just one second, you’d need to be released

Go on now, walk out the door. I’m not the same calling instance, you’re not needed anymore

Weren’t you the one who tried to create a reference cycle with goodbye, do you think I’d crumble, deallocate and die?

My value will survive!

Cue Sax solo.

p.s. you want self to live throughout the animation and possibly into completion. stay strong.

Apple Swift team undergoes reorganization

Statement from Chris Lattner:

Since Apple launched Swift at WWDC 2014, the Swift team has worked closely with our developer community.  When we made Swift open source and launched Swift.org we put a lot of effort into defining a strong community structure.  This structure has enabled Apple and the amazingly vibrant Swift community to work together to evolve Swift into a powerful, mature language powering software used by hundreds of millions of people.

I’m happy to announce that Ted Kremenek will be taking over for me as “Project Lead” for the Swift project, managing the administrative and leadership responsibility for Swift.org.  This recognizes the incredible effort he has already been putting into the project, and reflects a decision I’ve made to leave Apple later this month to pursue an opportunity in another space.  This decision wasn’t made lightly, and I want you all to know that I’m still completely committed to Swift.  I plan to remain an active member of the Swift Core Team, as well as a contributor to the swift-evolution mailing list.

Working with many phenomenal teams at Apple to launch Swift has been a unique life experience.  Apple is a truly amazing place to be able to assemble the skills, imagination, and discipline to pull something like this off.  Swift is in great shape today, and Swift 4 will be a really strong release with Ted as the Project Lead.

Note that this isn’t a change to the structure – just to who sits in which role – so we don’t expect it to impact day-to-day operations in the Swift Core Team in any significant way.  Ted and I wanted to let you know what is happening as a part of our commitment to keeping the structure of Swift.org transparent to our community.

-Chris

The Swift project is driven by a core team of Apple engineers:

The core team “reviews and helps iterate on language evolution proposals from the community at large, acting as the approver of these proposals. Team members help drive Swift forward in a coherent direction consistent with the goal of creating the best possible general purpose programming language.” They are appointed by the project lead.

Holy War: Type aliases

Kyle Cardoza writes: Erica, Is it considered bad style to typealias OpaquePointer when you have to deal with OpaquePointer values that point to different types? The typealiases make the code read so much nicer…

Using typealiases to create “pseudotypes” (where typealiases essentially duplicate a single  type) neatly organizes your code. I endorse any solution that emphasizes semantics and supports readability. As OpaquePointer is not generic, it doesn’t encapsulate type information the way Array<Int> or Set<String> do:

// Both are typed to OpaquePointer, so nothing concrete
// distinguishes the two roles.
// let p1 = OpaquePointer(unsafeMutableRawPtr1)
// let p2 = OpaquePointer(unsafeMutableRawPtr2)

Building convenience typealiases emphasizes the distinction between otherwise structurally identical uses. This differentiates each use-point and provides built-in “type commentary”:

typealias OpaqueType1Pointer = OpaquePointer
typealias OpaqueType2Pointer = OpaquePointer

let p1: OpaqueType1Pointer = OpaquePointer(rawPtr1)
let p2: OpaqueType2Pointer = OpaquePointer(rawPtr2)

// or, thanks Nil, directly:

let p1 = OpaqueType1Pointer(rawPtr1) 
let p2 = OpaqueType2Pointer(rawPtr2)

You might consider an alternative. If you’re willing to trade off a little overhead against enhanced type safety, you might introduce a simple value type. Wrapping the opaque pointer enables you to use a type-specific initializer. Here’s an extremely rough example of what that might look like:

struct SometypeWrapper {
    let opaque: OpaquePointer
    init(value: Sometype) {
        opaque = OpaquePointer(Unmanaged
            .passRetained(value).toOpaque())
    }
}

What do you think? Good use of type aliases? Bad? Or should you always go with a wrapper? Let me know. Drop a note in the comments or send over a tweet.

Thanks, Mike Ash

Forced Unwrapping URLs

Let me start with a little background. Laptopmini wanted to know why this code wasn’t compiling. Admittedly, Swift’s error messages leave room for improvement. The tl;dr was: he needed to swap the 2nd and 3rd lines of code. This allows both properties to be initialized before the code refers to self.


I immediately fixated on those exclamation points. “Are there any circumstances that these URLs will fail during creation? And if so, don’t you want to control that crash?” Laptop pointed out that there was no circumstance where his URLs would be malformed, and it was perfectly safe to use the exclamation point.

Despite this, his approach bugged my aesthetics. There’s no reason those URLs should be created in that initializer. I figured there were better ways to deal with this, moving URL creation out of the initializer and controlling crash landings with better error messages.

First, I considered extending URL to offer a safer non-optional initializer. The following snippet offers “controlled descent”, providing valuable feedback for any string that cannot be used to construct a URL.

extension URL {
    /// Non-optional initializer with better fail output
    public init(safeString string: String) {
        guard let instance = URL(string: string) else {
            fatalError("Unconstructable URL: \(string)")
        }
        self = instance
    }
}

This seemed too big a hammer for this problem. Instead, I decided to recommend the same approach with a solution localized to the SocketEndPoint type:

// Returns `URL` with guided fail
public enum SocketEndPoint: String {
    case events = "http://nowhere.com/events"
    case live = "http://nowhere.com/live"
    
    public var url: URL {
        guard let url = URL(string: self.rawValue) else {
            fatalError("Unconstructable URL: \(self.rawValue)")
        }
        return url
    }
}

This approach allows his init code to simplify. Under the updated design, it uses ordinary URLs in the initializer and no exclamation points.

// His initializer
fileprivate init() {
    self.eventSocket = WebSocket(url: SocketEndPoint.events.url))
    self.liveSocket = WebSocket(url: SocketEndPoint.live.url))
    self.eventSocket.delegate = self
    self.liveSocket.delegate = self
}

Long story short:

  • String enumerations are handy but SocketEndPoint wasn’t pulling its weight. Its job is to deliver named URLs. It should do that no matter however the type is implemented.  Don’t let types slack off because there’s an “almost there” solution baked into the language.
  • Keep initializers clean and simple.
  • When weighing a universal solution against a simple local one, sometimes it’s best to think small and fix the problem in the immediate context.
  • I considered normal URL construction (returning an Optional) and creating a WebSocket initializer with implicitly unwrapped optionals (public init(url: URL!)This approach offered no real advantages and lost the ability to report which string was malformed. Also, ugly.

You can see a few of approaches I kicked around at this gist.

Dear Erica: Singletons and Static Property Side Effects

Laptopmini writes, “Can you define a ‘get‘ closure for a singleton’s sharedInstance? I have a web socket manager and I’d like it to call ‘connect()‘ any time its instance is fetched”

A basic Swift singleton looks like this:

public final class Singleton {
    public static let shared = Singleton()
    private init() { }
}

This design creates a class with a single accessible shared instance. The class is marked final, and the initializer is private, ensuring the type cannot be subclassed or instantiated beyond shared.

To introduce side effects, create indirect access to the singleton and add your custom behavior to a getter:

public final class Singleton {
    private static let _shared = Singleton()
    private init() { }
    
    public static var shared: Singleton {
        get {
            print("side effects here")
            connect() // for example
            return _shared
        }
    }
}

This works but it’s a little more complicated than it has to be. As a get-only property, you can omit the get syntax. Just move the custom behavior to the top-level var clause, as in the following modification:

public final class Singleton {
    private static let _shared = Singleton()
    private init() { }
    
    public static var shared: Singleton {
        print("side effects here")
        connect() // for example
        return _shared
    }
}

Quick summary:

  • Use reference types for singletons.
  • Mark the type final, the instance public, and the initializer private.
  • When naming, prefer the Swiftier shared to the more Objective-C sharedInstance.
  • Create a static getter for any side effects.
  • Omit the get syntax for get-only properties.

Have some thoughts about improving this? As always, drop a note in the comments or tweet me and I’ll tweak.

Rob N has a good point here:

Reducing to Swift sets

A friend asked me, “Is there a better way to reduce to a set than .reduce (Set<String>()) { $0.union(CollectionOfOne($1)) } ?” He was fetching results from an external source and wanting to feed them into a set.

We kicked some ideas back and forth about how this could be implemented. Would he need to query the set before fetching all the items (no) and would his data set be so large that it would be impractical to store the intermediate results into an array before creating a set (also no).

I built a suite of tests, trying out his reduce method, using normal insertion, etc.  I assumed that using a Set initializer would probably be the best approach for a pre-computed array, but it turns out that union and insertion performed better in repeated tests:

timetest("initializer") { //  0.652348856034223
    var x: Set<String> = []
    (1 ... 5_000).forEach { _ in
        x = Set(letters)
    }
}

timetest("union") { // 0.524669112986885
    var x: Set<String> = []
    (1 ... 5_000).forEach { _ in
        x = x.union(letters)
    }
}

timetest("insert") { // 0.572339564969297
    var x: Set<String> = []
    (1 ... 5_000).forEach { _ in
        x = []
        letters.forEach ({ x.insert($0) })
    }
}

timetest("reduce") { //  0.762973523989785
    (1 ... 5_000).forEach { _ in
        var x = letters.reduce(Set<String>()) {
            $0.union(CollectionOfOne($1))
        }
    }
}

That surprised me since you’d imagine that  init<Source : Sequence where Source.Iterator.Element == Element>(_ sequence: Source) and func union<S : Sequence where S.Iterator.Element == Element>(_ other: S) -> Set<Element> would have similar performance characteristics.

What didn’t surprise me was that trying to create a set on the go cost more than storing intermediate results to an array and then building a set out of them. So long as the array was reasonably limited in size (that is large enough to be non-trivial but not so large that it put a burden on application memory), an intermediate array seems to be the better approach. Set(collectedResults) outperformed insert, formUnion, and reduce/union for non-trivial result sizes.