Handling Multiple Closure Parameters

So Natasha has a fair criticism about auto-completion1 in Xcode with regards to functions that take multiple closures and Swift's trailing closure syntax. I think there are many issues with auto-complete and Swift, but that's different rabbit hole to go down.

Instead, what I wanted to focus on was another way to solve the problem, which also helps with the auto-complete issue.

Here's the basic original problem:

func doSomething(value: Int, onSuccess: () -> (), onError: () -> ()) {
    if value == 0 {
        onSuccess()
    }
    else {
        onError()
    }
}

So instead of writing code in one the following ways (which all have the weird multiple closure issue):

doSomething(5, { println("success") }, { println("error") })
doSomething(0, { println("success") }) { println("error") }
doSomething(5, { println("success") }, { println("error") })

We can restructure the code using a very simple promise model.

struct CallbackResult<T> {
    let value: T
    let failed: Bool

    func onError(fn: (value: T) -> ()) -> CallbackResult<T> {
        if self.failed {
            fn(value: value)
        }

        return self
    }

    func onSuccess(fn: (value: T) -> ()) -> CallbackResult<T> {
        if !self.failed {
            fn(value: value)
        }

        return self
    }
}

func doSomething(value: Int) -> CallbackResult<Int> {
    return CallbackResult(value: value, failed: value != 0)
}

Then the usage becomes:

doSomething(10)
    .onSuccess { println("foo(\($0)): success") }
    .onError { println("foo(\($0)): error") }

doSomething(0)
    .onSuccess { println("foo(\($0)): success") }
    .onError { println("foo(\($0)): error") }

If you are familiar with JavaScript, you'll see a similar thing with deferred objects in jQuery and lots of other places as well.

There are lots of other benefits to this approach as well, such as helping flatten out async code that has a bunch of callbacks in it.

Anyhow, just another option.

  1. So I just realized that this was an old post of hers… auto-complete is still as terrible as ever though. Maybe one day.
Handling Multiple Closure Parameters