Skip to content

Instantly share code, notes, and snippets.

@oliverepper
Created November 28, 2022 10:04
Show Gist options
  • Save oliverepper/37b98caac658c38f639b5e2599c92119 to your computer and use it in GitHub Desktop.
Save oliverepper/37b98caac658c38f639b5e2599c92119 to your computer and use it in GitHub Desktop.
/*
* This is all Eric Nieblers work, see: https://youtu.be/h-ExnuD6jms
*/
import Foundation
protocol Initializable {
init()
}
protocol Receiver<T> {
associatedtype T
func setValue(_ value: T)
}
func newThread<T: Initializable>() -> (any Receiver<T>) -> Void {
return { r in
Thread {
r.setValue(T())
}.start()
}
}
func calcInt(executor: @escaping (any Receiver<Int>) -> Void) -> (any Receiver<Int>) -> Void {
then(executor, { _ in
return 42
})
}
struct ThenSender<T>: Receiver {
let p: any Receiver<T>
let next: (T) -> T
init(_ p: any Receiver<T>, _ next: @escaping (T) -> T) {
self.p = p
self.next = next
}
func setValue(_ value: T) {
p.setValue(next(value))
}
}
func then<T>(_ task: @escaping (any Receiver<T>) -> Void, _ next: @escaping (T) -> T) -> (any Receiver<T>) -> Void {
return { p in
task(ThenSender(p, next))
}
}
class Shared<T> {
var mtx = pthread_mutex_t()
var cv = pthread_cond_t()
var data: T!
init() {
pthread_mutex_init(&mtx, nil)
pthread_cond_init(&cv, nil)
}
}
struct Promise<T>: Receiver {
var shared: Shared<T>
func _set(_ value: T) {
pthread_mutex_lock(&shared.mtx)
shared.data = value
pthread_mutex_unlock(&shared.mtx)
pthread_cond_signal(&shared.cv)
}
func setValue(_ value: T) {
_set(value)
}
}
func sync_wait<T>(_ task: @escaping (any Receiver<T>) -> Void) -> T {
let shared = Shared<T>()
// start
task(Promise<T>(shared: shared))
// get
func _get() {
pthread_mutex_lock(&shared.mtx)
while shared.data == nil {
pthread_cond_wait(&shared.cv, &shared.mtx)
}
pthread_mutex_unlock(&shared.mtx)
}
_get()
return shared.data
}
extension Int: Initializable {}
let start = calcInt(executor: newThread())
let next = then(start, { i in return i / 2 })
print("Value: \(sync_wait(next))")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment