Archive for the ‘Swift’ Category

Holy War Part II: Son of Last Item in a Non-empty Array

Here are the two use cases motivating my Last Item in a Non-empty Array post. You can see the entire gist here.

The first method uses the guarantee of a non-empty array and notes it in an associated traditional comment. I have no problem with this. I should note that this second method is defined right after the method it builds on, and there’s little likelihood of confusion or review issues.

public func partitioned(where predicate: @escaping (_ element: Iterator.Element, _ mostRecent: Iterator.Element) -> Bool ) -> [[Iterator.Element]] {
    // `partitioned(at:)` guarantees a non-empty array
    // as its second closure argument
    return self.partitioned(at: {
        return predicate($0, $1.last!)
    })
}

The more serious problem is when you use the `partitioned(at:)` call outside the enclosing type. For example, you might want to partition an array at each point where the value changes:

testArray.partitioned(at: { $0 != $1.last! })

Looking at this one line of code, you have to make not just one but two mental leaps.

  • First there’s the correlation between the anonymous arguments and the call. Unlike partitioned(where:), which can be called for example with !=, this partitioned(at:) call takes two arguments, one of which is an element, and another an array of elements.
  • Second there’s the fact that there are no clues or information that the second anonymous argument is guaranteed to be non-empty, except if you note this in a comment or assertion or something like that.

If you use Xcode QuickHelp from this freestanding line of code, the non-empty guarantee is not visible:

The guarantee is only visible when used directly at the definition site:

Further, there’s a natural Swift coder tendency to question every exclamation point, namely: “Is this an intentional unwrap, with an expectation of failure should the unwrapping fail, or is it a naive use to shut up the compiler?”

Moving from forced unwrap to the lastOrDie workaround I mentioned in my original post makes user intent clear and explicit, and differentiates last from lastOrDie in Xcode’s pop-up completion list. It says: “This code should break on an empty array, which should never happen”. There’s a guarantee in place, implied by using lastOrDie.

You can mitigate forced unwraps with comments. (There’s an ongoing holy war about whether these kind of comments are appropriate or themselves bugs. Hi Soroush!)

// $1 is guaranteed as a non-empty array
testArray.partitioned(at: { $0 != $1.last! })

Or you can make the closure big and explicit. You might incorporate  an assert (will be removed from production code) or guard statement (won’t be), but this gets kind of ridiculous when you just want to force unwrap an item you know is going to be valid. Compare this mess to the original $0 != $1.last! solution:

testArray.partitioned(at: {

    (element: Int, currentPartition: [Int]) -> Bool in
    assert(!currentPartion.isEmpty, "Partition guaranteed to be non-empty")
    element != currentPartition.last!
})

Hopefully this provides the context missing from my original post. If you still have questions about why and how this is a problem, tweet, comment, or email. Thanks.

Holy War: Last Item in a Non-empty Array

Thoughts? Preferences? For the context behind this, see this post, and the screenshots in particular.

Option 1:

extension Array {
    /// Return last element for array that is guaranteed 
    /// to have at least one element
    public var lastOrDie: Element {
        assert(!self.isEmpty, "Array is guaranteed nonempty")
        let finalIndex = self.index(before: self.endIndex)
        return self[finalIndex]
    }
}

Option 2:

extension Array {
    /// Return last element for array that is guaranteed 
    /// to have at least one element
    public var lastOrDie: Element {
        guard let final = self.last
            else { fatalError("Failed to retrieve final array element") }
        return final
    }
}

Option 3:

extension Array {
    /// Return last element for array that is guaranteed 
    /// to have at least one element
    public var lastOrDie: Element {
        return self.last! // yes that's an exclamation point
    }
}

Option 4:

array.last!

Option 5:

// postfix operators cannot begin with either a 
// question mark or an exclamation mark.
postfix operator .!!!

extension Optional {
    /// "This unwrap is intentional" operator.
    /// G. Paltrow: "Conscious Unwrapping"
    /// Courtesy of: http://twitter.com/lapcatsoftware/status/856902513303449601
    public static postfix func .!!!(lhs: Optional) -> Wrapped {
        return lhs!
    }
}

Option 6:

The opinionated Tao of Optional Mappage

Given these two functions:

  • p(x) -> Void executes side effects in its body.
  • f(x) -> y produces a transformed value

Prefer:

  • if let x = x { p(x) } to x.map({ p(x) }) when executing a function for its side effects.
  • return x.map({ f(x) }) when returning a transformed value based on an optional.

You may think of map as inherently functional but x.map({ p(x) }) does not warn on unused result. In this case, the return type is Void. If  you assign the value, the compiler warns of the unexpected ()? return type.

I’ve often thought that forEach would be a better approach for procedural calls than map when working with optionals. This is based on the often disputed notion that optionals are like tiny collections with either zero or one members.

This is not how optionals are conceived, and the swift team has mentioned so on several occasions. Dmitri Gribenko wrote:

My argument is that map on collections and on optionals are two completely different things.  They unify on a level that does not exist in Swift (higher-kinded types).  We could name Optional.map() differently, and that would be a separate decision from renaming Collection.map(), but we used the name `map` primarily because of precedent, not because there is a HKT notion of these two operations
being the same…

I can’t say that it is not valid to think about an Optional as a tiny collection, but as implemented in Swift, .map() does objectively behave differently…Optional is a result of a computation that can fail.  .map() allows you to chain more things onto a computation if it succeeded, and do nothing if it failed already.

Until such things are resolved, you might consider replacing procedural calls on optionals with a custom forEach implementation:

extension Optional {
    public func forEach(perform action: (Wrapped) -> Void) {
        self.map(action)
    }
}

let x: String? = "Hello"
x.forEach { print($0) }

I think it better presents the notion that you’re not returning a value from mapping but executing a procedure for its side effects on any wrapped value within an optional.

What do you think?

Swift Documentation: Life Pro Tips

Swift Life Pro Tip: If you’re working with a Swiftized version of what was originally a Cocoa /Touch Foundation type, always check the header file just in case there’s more info that’s missing from the Swift version.

To take an example from a conversation today, consider the following code. What happens if you pass nil rather than an actual locale?

let string = "istanbul"
print(string.uppercased()) // ISTANBUL

import Foundation
let locale = Locale(identifier: "tr")
print(string.uppercased(with: locale)) 
// İSTANBUL, with the dot over the I

print(string.uppercased(with: nil))  // ??

Swift

Cocoa/Touch Foundation

Looking up Headers

The header files use traditional comments that I assume aren’t picked up by automatic document generation:

  1. Look up declaration for the NS version of a Swift Foundation class, such as NSString vs String.
  2. Click Objective-C and away from Swift.
  3. De-swiftize the `uppercase(with:)` declaration. In this case, the ObjC declaration is, `- (NSString *)uppercaseStringWithLocale:(NSLocale *)locale;`
  4. Find the header file (I have System/Library/Framework on perma-symbolic link from my home folder) and look there for NSString.h.
  5. Look at the original declaration in the header file:
/* The following methods perform localized case mappings based on the locale specified. Passing nil indicates the canonical mapping. For the user preference locale setting, specify +[NSLocale currentLocale].
*/

Hope this helps someone.

Tangentially, Zev Eisenberg reminds me to link to the Swift String Manifesto, which addresses a bit of this issue.

Got other Swift Life Pro Tips? Drop a comment, a tweet, or an email. Thanks!

Stupid Swift Tricks: Sleepsort

Was chatting today about the freestanding old style partition function and the new one that’s part of SE-0120. One thing led to another and I was writing sleepsort in a playground.

Several interesting things.

  • To Linuxize, so I could run this in the IBM sandbox, I had to import Dispatch, use CLOCKS_PER_SEC, and use rand() (and no, I didn’t even bother seeding it, I just wanted the code to run).
  • Bad things™ happened without the access queue, as the quality of service was not quite as good as I initially thought.
  • I had to tweak the delay time between the Linux and playground implementations a bit so closures didn’t fire unexpectedly and wouldn’t run over each other. Maybe I should have gone with a different policy than default for my primary dispatch method?

As always, if you have improvements or suggestions, fire ’em away.

Bridging Swift Generics with Darwin Calls

Seth Willits was working on an interpolation protocol that would allow conforming constructs to interpolate from one value to another, regardless of their underlying types. It needed to work for CGFloat as well as Double, and be decomposable and useful for CGPoint and CGRect as well as any custom Swift Polygon struct.

This created interesting challenges, as some of the most fundamental animation curves use exponentiation, which is not built into the Swift standard library. So I turned to pow, which is only defined for float and double:

public func powf(_: Float, _: Float) -> Float
public func pow(_: Double, _: Double) -> Double

In the past, I’ve created horrible bridging solution that permits migration from most floating point values to double. It’s not beautiful but I decided to pull it out from my toolkit and introduce it to this problem.

What I did was to build an extension on BinaryFloatingPoint that returned an interpolated value along a styled curve. My hack let me create a single interpolate method that applied across floating-point. I bridged to Double to use the Darwin pow function:

There’s an interesting CGFloat bug in play here, where the value history does not display as a graph but the numbers are right and work properly during animation.

Here’s the code. Shout out your improvements and alternatives.

Style this: Image Name

The Code

This episode of “Style this” stars code from Brandon Trussell, who asked to “make this Swiftier”:

// Get the image name
var imageName: String? = nil
if let collection = songs {
    for song in collection {
        if (song.cover_url != "") {
            imageName = song.cover_url
            break;
        }
    }
}

The Issues

So what’s wrong with this code? Here’s a quick overview.

Naming. There’s a mismatch here between imageName and cover_url. Is it a name? A URL? What? Turns out that this is a string, such as “ExperienceHendrix.jpg”. Both the cover_url property and the local imageName variable should reflect this better. And they do so without unsightly snake case naming. Fix: Rejigger the names to reflect that these are local file names and use standard Swift camelCase naming.

Parenthesized conditions and semicolons. The parentheses in the empty string check and the semicolon after the break are holdovers from Objective-C. Train yourself away from these reflexive habits. They’ll compile in Swift but they’re unnecessary. Fix: Ditch the parens and semicolon.

Comparing against an empty string. It’s bad form to test against an empty string or check if a collection’s count is zero. Prefer using the isEmpty property, which offers better semantics and performance. Fix: Refactor the empty string check.

Using an empty string instead of an optional. There’s a design flaw here in that this model should really use an optional String instead of an empty string to begin with (thanks Dave DeLong), but that’s another fish to fry that this redesign won’t address. In Swift, an optional represents the absence of a value in a way that an empty string does not convey.

Using the wrong type. The right type for a local file asset should be a file URL, not a string. Again, this redesign won’t address that.

Complex iteration: When you’re looking for the first member of a collection that satisfies a predicate, go functional. The Standard Library offers many ways to convert iteration that uses extra state (in this case the imageName variable) into a cleaner function call. Fix: use first(where:), which you get for free as part of the standard library.

Unnecessary conditional binding: If you’re going to use an optional value exactly once to extract some value and you can transform that binding into a function call, consider optional chaining instead. Fix: use songs? with a function.

The Refactor

Here’s what a refactored and Swiftier version of Brandon’s code might look like. This rewrite returns an optional string. That string contains the first non-empty coverImageFileName property within the songs collection. I think it’s a simpler approach with better naming and tighter code.

// Extract the file name for the first cover image
// found within the optional `songs` collection
let firstCoverImageFileName: String? = songs?
    .first(where: { !$0.coverImageFileName.isEmpty })?
    .coverImageFileName

Note that both calls in the functional chain require question marks. The first one, after songs, reflects that songs is an optional collection. The second, after the first(where:) call supports potentially nil searches (for example, where a collection has no covers).

This code won’t compile without that second question mark. Swift will, however, warn you at compile time that you’re attempting to make a call on an optional type if you omit it.

Soroush Khanlou, Dave DeLong, and Tim Vermeulen put their heads together for a slightly different approach:

let firstCoverImageFileName2: String? = songs?
    .lazy.flatMap({ $0.coverImageFileName })
    .first(where: { !$0.isEmpty })

Using a lazy flatMap may be a bit harder to wrap your head around, but it’s beautiful in that it pulls each image name, and then returns the first non-empty one, ensuring that you don’t create any intermediate storage.

Tim further adds:

extension Sequence {
    func firstResult<T>(_ transform: (Iterator.Element) -> T?) -> T? {
        for element in self {
            if let result = transform(element) {
                return result
            }
        }

        return nil
    }
}
let firstCoverImageFileName: String? = songs?
    .firstResult { 
        $0.coverImageFileName.isEmpty ? nil : $0.coverImageFileName }

and, as an alternative:

extension Optional {
    init(_ value: Wrapped, where predicate: (Wrapped) -> Bool) {
        self = predicate(value) ? value : nil
    }
}

songs?.firstResult { 
    Optional($0.coverImageFileName, where: { !$0.isEmpty }) 
}

Also, I threw together this, which I’m not sure if I hate or not:

extension Sequence {
    func first<T>(
        apply transform: @escaping (Iterator.Element) -> T?, 
        where predicate: @escaping (T) -> Bool) -> T? {
        return self.lazy
            .flatMap({ transform($0) })
            .first(where: predicate)
     }
}

songs?.first(apply: { song in song.coverImageFileName }, 
    where: { name in !name.isEmpty } )

Swift Style

Agree with these refactoring recommendations? Disagree? Would you redesign this differently? Drop a comment or send a tweet. Swift Style is now available to order as a paper book, an ebook, and a paper/ebook bundle.

Tip of the hat to Mike Ash who was also offering feedback. Thanks to Soroush Khanlou, Dave DeLong, Tim Vermeulen, Zev Eisenberg

Dear Erica: Working synchronously with asynchronous calls

How do I wait for an asynchronous closure? I am making an async network request and getting its results in a closure but somewhere I have to know that my request has been completed so I can get the values

You can approach this several ways. The easiest is to post a notification or call a delegate method from your completion handler. Make sure you stay aware of the thread you’re working with. You may need to dispatch to the main thread to perform your delegation, callbacks, or notifications.

When you’re working with several tasks that must finish before moving forward, use a dispatch group to keep count until they’re all done, and then send your update information.

If you truly need to stop execution until the request returns (and this is usually a bad thing with the possible exception of synchronous execution in playgrounds), you can use a run loop to stop things until your asynchronous call returns control.  This breaks a lot of best practice rules. It  can be mighty handy when you don’t want to start building lots of helper classes in a quick demo or proof of concept, where the emphasis is on procedural tasks.

Musings on Partial Application

I tend to use the phrases currying and partial application interchangeably. The Intertubes tell me, however,  that currying is limited to 1-arity stages. Arity refers to the number of a function’s arguments and should not be confused with Arrietty from the Borrowers.

Swift is tuple friendly and given tuples, I mentallly stretch the “same thingity” thinking to partial application as currying so long as the tuples reflect an underlying coherent structure. This is probably wrong and evil, but what are you going to do?

Swift officially removed currying™ in Swift 3 but it didn’t remove partial application, the ability to create a function of smaller arity, where some parameters have already been assigned.

Consider the following function. It accepts a low and a high bound and clamps a value inclusively within those bounds. You must pass the low and high values each time you call the function:

func clamp<T: Integer>(min minValue: T, 
    max maxValue: T, _ value: T) -> T {
    return min(max(value, minValue), maxValue)
}

clamp(min: 2, max: 5, 25) // 5
clamp(min: 2, max: 5, -25) // 2
clamp(min: 2, max: 5, 3) // 3

Partial application enables you to break down the function, to create a reusable component specific to some pair of bounds:

func clampRange<T: Integer>(min minValue: T, max maxValue: T)
    -> (_ value: T) -> T {
    return { value in
        min(max(value, minValue), maxValue)
    }
}

// For example
let clamp25 = clampRange(min: 2, max: 5)
clamp25(25) // 5
clamp25(-25) // 2
clamp25(3) // 3

Swift does not use argument labels in function types, which is why I do not use a label for the value argument. If I were not thinking in terms of partial application, I might have added a value label for the 3-argument version.

As Mike Ash pointed out today, another way to partially apply a function is to create a separate function or closure. Use positional arguments to populate the missing parameters:

let clamp25 = { clamp(min: 2, max: 5, $0) }
clamp25(25) // 5
clamp25(-25) // 2
clamp25(3) //3

It’s a lot cleaner and shorter than the standard approach and, if you like, you can use closure signatures to eliminate anonymous parameters:

let clamp25 = { value in clamp(min: 2, max: 5, value) }

Note that the calls won’t change. Function types cannot have argument labels.

Defaulted parameters kind of look like a partial application, but they really aren’t. You must decide a priori what your defaulted values are, which limits the way you reduce functional arity to a single fixed set of fallback values:

func clamp<T: Integer>(min minValue: T = 2, 
    max maxValue: T = 5, _ value: T) -> T {
    return min(max(value, minValue), maxValue)
}

clamp(25) // 5
clamp(-25) // 2
clamp(3) // 3

I find myself using partial application a lot in graphics, particularly when applying perspective or layout transformations. Until now, I’ve been using the standard -> -> -> approach. Today Mike has made me think that maybe I should consider closures instead, where I’ve partially applied the function to some parameters.

Dear Erica: Creating a conditional assignment operator

Manuel Carlos asks whether it’s possible to create an operator that executes a closure and returns a value based on whether a condition is true. Here’s his initial attempt:

My recommendation? Skip the operator and just use an if-statement:

if true { v = 100 } // vs v = 100 <-? true
if false { v = 100 } // vs v = 100 <-? false
if true { print("hello") } // vs print("hello") <-? true
if false { print("hello") } // vs print("hello") <-? false

Yes, it’s simple, but simple gets the job done without straining or extending the language. There’s little gained in building a more complex logic-driven assignment for this use case. Placing a truth statement to the right of each action inverts the normal way people read code, burns an operator, abuses auto-closure, and unnecessarily complicates what should be a straightforward operation.

That’s not to say this isn’t an interesting design space. Although Swift does not support custom ternary operators at this time, it may do so at some point in the future. Even then, I’d be cautious about replacing if-then control with such complex solutions.

Apple’s recommendations on auto-closure are:

  • Use autoclosure carefully as there’s no caller-side indication that argument evaluation is deferred.
  • The context and function name should make it clear that evaluation is being deferred.
  • Autoclosures are intentionally limited to take empty argument lists.
  • Avoid autoclosures in any circumstance that feels like control flow.
  • Incorporate autoclosures to provide useful semantics that people would expect (for example, a “futures” or “promises” API).
  • Don’t use autoclosures to optimize away closure braces.

Want to read more about Swift Style? There’s a book!