Archive for January, 2017

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.

Overdrive, DRM, and Adobe Digital Editions

The Denver library recently migrated its ebook system. Incidentally, it wiped all my holds in the process and I have no idea what stuff I was waiting to read. So if you recced anything over the past 6 months and it was popular, chances are that I need you to remind me to read it again.

Anyway, today my first hold came in on the new system. I downloaded the ascm file as usual, double clicked, and when Adobe Digital Editions opened, I got this on my screen:

Yikes. I immediately assumed it was time to update Adobe Digital Editions. So I did that. And I tried opening it up again and I got this:

While you can see the massive UI improvements Adobe has made to its signature Mac e-reader, I was still rather stuck.

So I googled for E_ACT_NOT_READY and “IO Error on Network Request” and tried all the things that didn’t work until I found something that did work.

What didn’t work:

  • Clearing out ~/Documents/Digital Editions
  • Creating a new ~/Documents/My Digital Editions
  • Quitting and restarting the apps
  • Rebooting

What did work was reauthorizing my computer. Dunno why. I deauthorized and then reauthorized — good thing I remembered my username and password because it has been a gadzillion years since I did this last — and boom it finally worked.

(If you want to remove authorization by hand, toddle over to ~/Library/Application Support/Adobe/Digital Editions and kill the activation.dat file.)

Anyway, Scott Sigler’s “Alive” is now on my system ready for reading. I have no idea why I put this title on hold and who recommended it to me. I hope it’s good. Here’s finger’s crossed that this is a good read.

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.

Why we develop

From my inbox:

I have been steadily using folderol in order to help me define which folders are important, as well as which ones are not.

Folderol has also been handy to me in developing subfolders within folders and having those subfolders be different colors, which helps me find the information inside of them quicker.

Thank you for developing such a great product.  If the folderol app is any indication of other products that you might have developed or that are in the development stage, I look forward to seeing what other applications you have.

Respectfully,

Demetrius Moyston

Folderol at the Mac App Store

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