Hi Ben,

Is there any difference to this altered version of your example?

func foo(_ test: () -> Int) {
    print(#function, test())
}

func bar(_ test: () -> Int) {
    foo(test)
}

func baz(_ test: @autoclosure () -> Int) {
    bar(test)
}

baz(42)
It looks exactly the same to me. After the pitched change one could finally 
pass a normal closure with the same signature to a function that takes an 
autoclosure, which then won’t wrap.

In the following example @autoclosure wins over a concrete closure type and 
produces a false result, because it will wrap () -> Void into () -> (() -> 
Void). I kinda have a feeling that the proposed change (#2) will resolve this 
issue, but I don’t have the insights on what @autoclosure does exactly to the 
closure type.

extension Bool {

    /// #1
    func whenTrue(execute closure: () -> Void) {
        if self { closure() }
    }

    /// #2
    func whenTrue(execute closure: @autoclosure () -> Void) {
        if self { closure() }
    }

    /// #3
    func whenTrue<T>(execute closure: @autoclosure () -> T) -> T? {
        if self { return closure() }
        return nil
    }
}

let test: () -> Void = { }

true.whenTrue(execute: test) // #3 wins, but I expect #1 here
Ideally I would want a single function that handles every case:

// Does not wrap when a closure `() -> T` is passed to it, because of #2
@discardableResult
func whenTrue<T>(execute closure: @autoclosure () -> T) -> T? {
    if self { return closure() }
    return nil
}


-- 
Adrian Zubarev
Sent with Airmail

Am 25. Juni 2017 um 09:03:09, Ben Rimmington ([email protected]) schrieb:


On 24 Jun 2017, at 17:10, Adrian Zubarev wrote:

2. Make @autoclosure only wrap when necessary:

func bar(_ test: @autoclosure () -> Int) {
    print(test())
}

let test = { 42 }

// function produces expected type 'Int'; did you mean to call it with '()'?
bar(test)

Note that you can forward an autoclosure to another function:
Welcome to Apple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42).
  1> func foo(_ test: @autoclosure () -> Int) {
  2.     print(#function, test())
  3. }
  4.  
  5. func bar(_ test: @autoclosure () -> Int) {
  6.     foo(test)
  7. }
  8.  
  9. func baz(_ test: @autoclosure () -> Int) {
 10.     bar(test)
 11. }
 12.  
 13. baz(42)
foo 42
 14>  

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to