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