[swift-evolution] [Pitch] Extending [at]autoclosure

Adrian Zubarev adrian.zubarev at devandartist.com
Sun Jun 25 03:05:45 CDT 2017


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 (me at benrimmington.com) 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>  

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170625/9d2bf54e/attachment.html>


More information about the swift-evolution mailing list