[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