Skip to content

Instantly share code, notes, and snippets.

@slazyk
Created June 5, 2014 13:59
Show Gist options
  • Save slazyk/e82431f50a564323245f to your computer and use it in GitHub Desktop.
Save slazyk/e82431f50a564323245f to your computer and use it in GitHub Desktop.
Fun with Swift
import Foundation
class VoidTask {
let group : dispatch_group_t
func waitUntilDone () -> () {
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
}
init(_ task: () -> (), queue: dispatch_queue_t? = nil) {
let q = queue ? queue! : dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
self.group = dispatch_group_create()
dispatch_group_async(group, q, task)
}
// //not really a good idea ;)
// deinit {
// waitUntilDone ()
// }
}
class Task<R>: VoidTask {
// R[] is a quick and dirty workaround, having R? here causes:
// error: unimplemented IR generation feature non-fixed class layout
var results : R[]
func value () -> R {
waitUntilDone ()
return results[0]
}
init(_ task: () -> R, queue: dispatch_queue_t? = nil) {
results = []
super.init({ self.results = [task ()] }, queue: queue);
}
}
func async (f: () -> ()) -> VoidTask {
return VoidTask {
return f()
}
}
func async <R> (f: () -> R) -> Task<R> {
return Task {
return f()
}
}
func async <A, R> (f: A -> R) -> A -> Task<R> {
return { args in
return Task<R> {
return f(args)
}
}
}
func await <R> (task: Task<R>) -> R {
return task.value ()
}
@prefix func ! <R> (task: Task<R>) -> R {
return await(task)
}
operator infix ~ { }
@infix func ~ <A, R> (f: A -> R, args: A) -> Task<R> {
return async(f)(args)
}
func seriousComputation () -> Int {
println("starting serious computation")
sleep(3)
println("finished serious computation")
return 42
}
// create a task directly
let x = Task<String> {
sleep(1)
return "Swift"
}
// or use async { ... } unfortunetely () -> T in is required
let y = async { () -> String in
sleep(1)
return "is"
}
// ... unless it is () -> ()
async {
sleep(5)
println("you shall not pass")
}
// you can await tasks inside other tasks
let z = async { () -> String in
let w = ["c", "o", "o", "l"].reduce("") { (a, b) in
sleep(1)
return a + b
}
return "\(!x) \(!y) \(w)"
}
// can either await(x) or !x
println(!z)
println(await(z))
// can either async(seriousComputation)() or seriousComputation~()
let answer = seriousComputation~()
println("can't wait for the answer!")
println(await(answer))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment