     /// - parameter closure: The closure is called immediately on the current
     /// thread. You should start an asynchronous task and call either `succeed`
     /// or `fail` when it completes.
-    public convenience init(_ closure: (_ succeed: @escaping (Value) -> Void, _ fail: @escaping (Error) -> Void) -> Void) {
-        self.init(queue: .main, closure)
-    }
-
-    convenience init(queue: DispatchQueue, _ closure: (_ succeed: @escaping (Value) -> Void, _ fail: @escaping (Error) -> Void) -> Void) {
+    /// - parameter queue: A queue on which the future is observed. `.main` by
+    /// default.
+    public convenience init(queue: DispatchQueue = .main, _ closure: (_ succeed: @escaping (Value) -> Void, _ fail: @escaping (Error) -> Void) -> Void) {
         self.init(queue: queue)
-        closure({ self.succeed($0) }, { self.fail($0) }) // retain self
+        closure(self.succeed, self.fail) // retain self
     }
 
     init(queue: DispatchQueue = .main) {

/// functions like `map`, `flatMap`, `zip`, `reduce` and more to compose futures.
///
/// By default, all of the callbacks and composing functions are executed on the
/// main queue (`DispatchQueue.main`). To change the queue use `observeOn` method
/// which creates a new future observed on the given queue.
public final class Future<Value, Error> {
    private var state: State = .pending
    private var handlers: Handlers? // nil when finished

public struct Promise<Value, Error> {
    public let future: Future<Value, Error>

    public init(queue: DispatchQueue = .main) {
        self.future = Future(queue: queue)
    }

