Brisk (2016)

Back in 2016, well before Swift had native async/await, asynchronous code in Swift looked a lot like asynchronous code in Objective-C: closures nested inside closures nested inside closures, with every async API forcing you to wrap the next step of your logic in another callback. Brisk was my attempt to hide that mess behind a small DSL.

The core idea was a handful of custom infix operators that let you write async-feeling code in a synchronous-looking flow. <<+ would call an async function and block until it returned on the main queue, <<~ would do the same on a background queue, +>> would dispatch a closure asynchronously to main, and so on. So instead of this:

findClosestPokemon { pokemon, error in
    countPokeballs { number, error2 in
        throwPokeballAt(pokemon: p) { success, error3 in
            completionHandler(success: success, error: error3)
        }
    }
}

You could write something like this:

myQueue.async {
    let (pokemon, error)  = <<+{ findClosestPokemon(completionHandler: $0) }
    let (number, error2)  = <<~{ countPokeballs($0) }
    let (success, error3) = <<+{ throwPokeballAt(pokemon: p, completionHandler: $0) }
    completionHandler +>> (success: success, error: error3)
}

I also threw in some convenience extensions on DispatchQueue — delayed execution, repeated execution, deduplicated once(operationId:) calls — for the kinds of GCD patterns I kept rewriting from scratch in every project.

Brisk had a pretty short shelf life. Once Swift 5.5 landed with real async/await, everything Brisk was solving became a language feature, and the operators stopped playing nicely with newer Swift compilers anyway. I mothballed it.

Source on github.