Archive for the ‘Swift’ Category

Dear Erica: Snake Case

An anonymous reader writes, “Is there is ever a good reason to use snake case in Swift code?”

Although I’m tempted to respond with a snarky no_there_isn't, of course you’ll use snake case, and with good reason. The real world offers many legacy and non-native libraries. Coders often source snake case calls and constants in their production code.

When developing your own symbols, the Swift community consensus has centered on UpperCamel for type and protocol names and lowerCamel for members, freestanding functions, and other symbols. This is a non-binding convention but it will make your code look and feel more Swifty.

Swift 4: Release Process and Phase 2

Release Process

The Swift 4 release process targets Fall 2017:

Swift 4 is a major release that is intended to be completed in the fall of 2017. It pivots around providing source stability for Swift 3 code while implementing essential feature work needed to achieve binary stability in the language. It will contain significant enhancements to the core language and Standard Library, especially in the generics system and a revamp of the String type. More details can be found on the Swift Evolution page.

Swift 4 Phase 2

The Swift 4 two-stage release plan was established in July 2016: focusing on essentials and ABI stability.  Swift  4 only focuses on Phase 1 at this time. Stage 2 starts now.

All design work and discussion for stage 2 extends to April 1, 2017. The intent is to timebox discussion to provide adequate time for the actual implementation of accepted proposals.

Deferred ABI and Status Updates

Ted Kremenek writes,

Since July, we now have a much better understanding now of how to achieve ABI stability, with an ABI Manifesto https://github.com/apple/swift/blob/master/docs/ABIStabilityManifesto.md detailing the list of all language/implementation work that is needed to achieve ABI stability. We have made substantial progress in that work during stage 1, but much remains to be done. Once Swift achieves ABI stability the ABI can be extended, but not changed. Thus the cost of locking down an ABI too early is quite high.

Deferring ABI stability enables Swift to focus on language fundamentals. An ABI dashboard will be wired up from the Swift Evolution Github repository. This will present a table of remaining ABI tasks and display their status.

Foundation

Swift Foundation API improvements are folded under the phase 2 umbrella, “to continue the goal of making the Cocoa SDK work seamlessly in Swift. Details on the specific goals will be provided as we get started on Swift 4 stage 2.”

Unimplemented Proposals

The following accepted proposals are rolled forward into Swift 4 Stage 2:

  • SE-0104 “Protocol-oriented Integers”: This proposal requires revision and another round of review based on other changes that have been made to the language and standard library since acceptance.
  • SE-0075 “Adding a Build Configuration Import Test”: This is (still) an additive proposal and no other changes affect this proposal. It will be carried forward and considered accepted for Swift 4.
  • SE-0042 “Flattening the function type of unapplied method references”: This proposal requires another round of review. This is a significant source-breaking change, and the bar for such source-breaking changes is considerably higher in Swift 4 than it was in Swift 3.
  • SE-0068 “Expanding Swift Self to class members and value types”: This is (still) an additive proposal and no other changes affect this proposal. It will be carried forward and considered accepted for Swift 4.

Links

Swift Style: Now Available for Amazon Pre-Order

Swift Style is almost wrapped up. I’m just waiting for some final copy edits. Notably, pre-orders are live on Amazon. (You can ignore the dates, page counts, etc there. They’re just place-fillers.) I just did a product video for Amazon, which hopefully will be posted over the next few weeks.

Once printed, Style will be on sale at all the major retailers as well as at Pragmatic. Pragmatic gives you the option of hybrid ebook/printed bundles, and gives me a slightly better slice of the royalty pie, if that matters to you. It’s a nice thing for me.

I’ll be remote talking about the book and Swift Style at PlaygroundsCon on the 24th (the 23rd in the US) this month and Forward Swift 2 on March 2. I also recently gave a talk at Realm’s Swift user SLUG meetup, which you can watch by following the link earlier in this sentence.

That’s not to say this project is done. Swift Style evolved from talking to developers. It represents viewpoints from the larger Swift development community. That process can and will continue as people read the book and I expand its guidance. The people at Pragmatic have been lovely in helping me plan out the book’s future as well as its present.

Challenge: Filtering associated value enumeration arrays

The Challenge

Courtesy of Mike Ash, here’s the challenge. You have an enumeration:

enum Enum {
    case foo(Int)
    case bar(String)
    case qux(Int)
}

And you have an array of them:

let items: [Enum] = [.foo(1), .bar("hi"), .foo(2)]

Return a filtered array containing only one case, for example foo. The difficulty lies in that Swift does not seem to offer a == or ~= operator that works on cases, ignoring associated values:

// does not work
let filtered = items.filter({ $0 == .foo })

So what do you do?

Attempt 1

Here’s my first attempt. Super ugly but it gets the job done:

let filtered = items.filter({ 
    switch $0 { case .foo: return true; default: return false } })

Evan Dekhayser prefers if-case:

let filtered = items.filter({ 
    if case .foo = $0 { return true }; return false })

And you can of course use guard as well:

let filteredy = items.filter({ 
    guard case .foo = $0 else { return false }; return true })

Attempt 2

Just as ugly but slightly shorter in terms of number of characters. But it does more work than #1:

let filtered = items.filter({ 
    for case .foo in [$0] { return true }; return false })

Again, yuck.

Attempt 3

I really hate this approach because you have to implement a separate property for each case. Double yuck:

extension Enum {
    var isFoo: Bool {
        switch self { case .foo: return true; default: return false }
    }
}
let filtered = items.filter({ $0.isFoo })

Attempt 4

This is gross because it requires a placeholder value for the rhs, even though that value is never used. And no, you can’t pass an underscore here:

extension Enum {
    static func ~= (lhs: Enum, rhs: Enum) -> Bool {
        let lhsCase = Array(Mirror(reflecting: lhs).children)
        let rhsCase = Array(Mirror(reflecting: rhs).children)
        return lhsCase[0].0 == rhsCase[0].0
    }
}
let filtered = items.filter({ $0 ~= .foo(0) })

Attempt 5

Then I got the idea into my head that you could use reflection. If you don’t supply a value to an enumeration case with an associated value, it returns a function along the lines of (T) -> Enum. Here is as far as I got before I realized the enumeration *name* was not preserved in its reflection:

import Foundation

extension Enum {
    var caseName: String {
        return "\(Array(Mirror(reflecting: self).children)[0].0!)"
    }
    
    static func ~= <T>(lhs: Enum, rhs: (T) -> Enum) -> Bool {
        let lhsCase = lhs.caseName
        let prefixString = "Mirror for (\(T.self)) -> "
        let typeOffset = prefixString.characters.count
        let typeString = "\(Mirror(reflecting: rhs).description)"
        let rhsCase = typeString.substring(from: typeString.index(typeString.startIndex, offsetBy: typeOffset))
        return true
    }
}

Yeah. Really bad, plus it doesn’t work.

Call for solutions

Since I didn’t really get very far with this, I’m throwing this out there as an open challenge. Can you come up with a parsimonious, readable, and less horrible (I was going to say “more elegant”, but c’mon) way to approach this? I suspect my first attempt may be the best one, which would make me sad.

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.