Archive for April, 2017

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.