Created
June 5, 2014 13:59
-
-
Save slazyk/e82431f50a564323245f to your computer and use it in GitHub Desktop.
Fun with Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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