I feel strongly that you shouldn’t be using autoclosure in these cases. 
Instead, write `true.whenTrue { … }` and `true.whenTrue(myClosure)`.

> On Jul 1, 2017, at 3:17 PM, Adrian Zubarev <[email protected]> 
> wrote:
> 
> I clearly disagree with your point. Autoclosure supposed to be a 
> syntactically convenience feature to omit braces, which as a consequence 
> needs to disable arguments. However it is not said that you cannot pass a 
> closure with the same signature to the autoclosure, which currently is not 
> possible unless it’s another autoclosure. This doesn’t feel right at all.
> 
> func foo(_: @autoclosure () -> Void) {}
> 
> func bar(_ test: @autoclosure () -> Void) {
>    foo(test) // works    
> }
> 
> let closure: () -> Void = {}
> 
> foo(closure) // error
> Here is another example where autoclosure takes over and produces false 
> result even when the correct overload is present but the resolution ends up 
> picking an autoclosure.
> 
> 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 = { }
> // #3 wins and produces a wrong type () -> (() -> Void)?, but I expect #1 here
> // () -> Void?
> true.whenTrue(execute: test)  
> A syntactical convenience feature should not disable explicitness!
> 
> 
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 1. Juli 2017 um 19:46:55, [email protected] 
> <mailto:[email protected]> ([email protected] 
> <mailto:[email protected]>) schrieb:
> 
>> 
>> 
>> On Jun 30, 2017, at 1:48 AM, Adrian Zubarev via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>>> Well as Jordan Rose said on the linked SR, option (1) will probably never 
>>> happen. Option (3) only makes sense if all of the options are supported (in 
>>> that case there wouldn’t be any need for explicit @autoclosure, which could 
>>> simply be merged into the closure type), or (2) is NOT supported so that 
>>> one could pass a default autoclosure.
>>> 
>>> It leaves us only with (2), which is potentially a (small) breaking change, 
>>> but it also feels more like a fix. I cannot imagine anyone is wrapping 
>>> whole closures with auto closure, nor do I think a ‘convenience’ operation 
>>> should disable the explicit ability to pass in a closure with the same 
>>> signature. The latter feels like a bug. Furthermore I think most code that 
>>> relies on this is already doing something like.
>>> 
>>> func bar(_ closure: @autoclosure () -> Int) { foo(closure)}
>>> 
>>> func foo(_ closure: () -> Int)
>>> But this is only an assumption of mine.
>>> 
>>> Theoretically it suppose to work the other way around, right? Again 
>>> @autoclosure supposed to be a syntactical convenience feature which implies 
>>> that it won’t disable *too* much from the closure type. Disallowing 
>>> arguments is logical consequence but not the other issues I mentioned here 
>>> and in the SR.
>>> 
>>> —
>>> 
>>> One question: Do we need to go through a full evolution process for pitch 
>>> (2) or is a bug report enough here?
>>> 
>> Surely the former—I'm fully against this change, and imagine others are 
>> also. Autoclosure exists to provide opt-in lazy evaluation of values by 
>> wrapping them in a closure. I think it's semantically incorrect to accept an 
>> already wrapped value here, and adding this sort of implicit conversion can 
>> introduce potential ambiguity when used with generic functions.
>> 
>> Very large -1.
>>> 
>>> 
>>> -- 
>>> Adrian Zubarev
>>> Sent with Airmail
>>> 
>>> Am 30. Juni 2017 um 00:59:45, Beta ([email protected] 
>>> <mailto:[email protected]>) schrieb:
>>> 
>>>> These are all interesting ideas at first blush, but introduce some 
>>>> oddities into the type system
>>>> 
>>>> 1. We accept this 😳.  If we were to take this as an official language 
>>>> change it would mean that we would allow coercing T to (_) -> T by 
>>>> emitting a closure that takes an argument list (of arity given by the 
>>>> contextual type) that we throw away anyways.  I would much prefer we 
>>>> diagnose this instead.  @autoclosure is a syntactically convenient way to 
>>>> ask for laziness - that’s it.
>>>> 
>>>> 2. Doing this collapses overloads on @autoclosure
>>>> 
>>>> func foo(_ f : @autoclosure () -> String) {}
>>>> func foo(_ f : () -> String) {}
>>>> 
>>>> 
>>>> Which is fine by me except for the code you would break that relies on 
>>>> this.  I don’t see a reasonable migration path here - perhaps you have one 
>>>> in mind.
>>>> 
>>>> 3. @autoclosure is a parameter attribute.  Allowing it to appear in other 
>>>> positions is redundant and doesn’t actually accomplish anything outside of 
>>>> maintaining consistency with the first point.
>>>> 
>>>> I hope I don’t come off as too harsh.  It’s just a little shocking to me 
>>>> that we accept the code in the linked SR.
>>>> 
>>>> ~Robert Widmann
>>>> 
>>>>> On Jun 24, 2017, at 9:10 AM, Adrian Zubarev via swift-evolution 
>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>> 
>>>>> Hello folks,
>>>>> 
>>>>> Here is a quick and straightforward pitch about @autoclosure. Currently 
>>>>> the attribute indicates that the caller has to pass an expression so that 
>>>>> the braces can be omitted. This is a convenient behavior only, but it 
>>>>> also has it’s shortcomings.
>>>>> 
>>>>> I would like to propose an extension of that behavior.
>>>>> 
>>>>> 
>>>>> 1. Allow access to arguments and shorthand argument names:
>>>>> // Bug: https://bugs.swift.org/browse/SR-5296 
>>>>> <https://bugs.swift.org/browse/SR-5296>
>>>>> func foo(_ test: @autoclosure (Int) -> Int = { $0 }) {
>>>>>     print(test(42))
>>>>> }
>>>>> 
>>>>> // Convenient access using shorthand arguments
>>>>> foo(Int(Double($0) * 3.14)))
>>>>> 
>>>>> 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)
>>>>> 
>>>>> 3. Extend @autoclosure to closure types in general (this change is for 
>>>>> consistent alignment):
>>>>> // Note how we're using the shorthand argument list for this expression
>>>>> let uppercaseWrapper: @autoclosure (String) -> String = $0.uppercased()
>>>>> 
>>>>> 
>>>>> 
>>>>> -- 
>>>>> Adrian Zubarev
>>>>> Sent with Airmail
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> [email protected] <mailto:[email protected]>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 

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

Reply via email to