[swift-evolution] Code blocks and trailing closures
Rien
Rien at Balancingrock.nl
Wed Mar 15 07:17:09 CDT 2017
> On 15 Mar 2017, at 13:04, Jaden Geller <jaden.geller at gmail.com> wrote:
>
> It seems like your complaint is that control-flow statements, specifically `return`, act different inside closures than inside other braced statements.
Yes.
break and continue also come to mind.
For example if you have some nested loops and you see a “break” statement, you must inspect the code between the loop start and the “break" to check if the break is inside a closure or not.
> I too dislike this inconsistency, but I don’t think that the syntactic change you suggested makes it much more clear.
Agree.
As is probably clear from Adrian’s reaction, I am not sure if this really is a problem.
I don’t like it, but the current situation is workable even though it might be confusing to newbies.
> I’d rather find a solution that’d allow trailing closure functions (like `forEach`) to support keywords like `return`, though I imagine this would require some sort of macro system.
>
> Cheers,
> Jaden Geller
>
>> On Mar 15, 2017, at 4:56 AM, Rien via swift-evolution <swift-evolution at swift.org> wrote:
>>
>> Sorry, it seems we are talking past each other, let me try again:
>>
>> I left the “if” out on purpose. To show that even though the snippet was “valid” code, it was in fact ambiguous.
>>
>> With closures (and autoclosures) it becomes possible -to some extent- to “enhance” the language.
>>
>> Consider:
>>
>> guard let c = somefunc() else { showError(); return }
>> myguard( let c = somefunc()) { showError(); return }
>>
>> In this simple example it is clear that the second return behaves quite differently from the first.
>> It gets more difficult if the code in the block cq closure gets very large.
>> Also, I would expect that beginners would have problems understanding this (subtile but important) difference.
>>
>> Regards,
>> Rien
>>
>> Site: http://balancingrock.nl
>> Blog: http://swiftrien.blogspot.com
>> Github: http://github.com/Balancingrock
>> Project: http://swiftfire.nl
>>
>>
>>
>>
>>
>>> On 15 Mar 2017, at 12:19, Adrian Zubarev <adrian.zubarev at devandartist.com> wrote:
>>>
>>> There is no if … on my screen nor there is one here https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon–20170313/033888.html. May be a typo?
>>>
>>> In that case it cannot be a trailing closure because trailing closures are banned in such scenarios. https://github.com/apple/swift-evolution/blob/master/proposals/0056-trailing-closures-in-guard.md
>>>
>>> As for the lazy variables you’ve mentioned in the original posts, the closure there is invoked lately but only once and it cannot be reused at all.
>>>
>>> Let me know if I understood your gist now.
>>>
>>> if someFunction { …; return } // someFunction cannot have a trailing closure here!
>>>
>>>
>>>
>>>
>>> --
>>> Adrian Zubarev
>>> Sent with Airmail
>>>
>>> Am 15. März 2017 um 12:08:19, Rien (rien at balancingrock.nl) schrieb:
>>>
>>>> If I wrote this:
>>>>
>>>> if serverCert.write(to: certificateUrl) { showErrorInKeyWindow(message); return }
>>>>
>>>> then the meaning of return would have been different.
>>>>
>>>> Imo it is a problem that two pieces of code impact the understanding of each other and that those two pieces of code could potentially be very far apart.
>>>>
>>>> I do agree that the parenthesis are not a perfect solution, it was just the first thing that I could think of and that has some level of similarity in meaning.
>>>>
>>>> Regards,
>>>> Rien
>>>>
>>>> Site: http://balancingrock.nl
>>>> Blog: http://swiftrien.blogspot.com
>>>> Github: http://github.com/Balancingrock
>>>> Project: http://swiftfire.nl
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>> On 15 Mar 2017, at 12:00, Adrian Zubarev <adrian.zubarev at devandartist.com> wrote:
>>>>>
>>>>> I’m slightly confused by this. How is a trailing closure different from a code block in Swift? It’s basically the same thing with some extra syntax sugar because it happens to be the last parameter of your function.
>>>>>
>>>>> You can simply write this if you wanted to:
>>>>>
>>>>> myFucntion(someLabel: abc, closureLabel: { …; return })
>>>>>
>>>>> Parentheses are indicating that your closure is immediately invoked.
>>>>>
>>>>> let someInt = { return 42 }()
>>>>> print(someInt)
>>>>>
>>>>> let someClosureWhichReturnsAnInt = { return 42 } // You can reuse the closure
>>>>> print(someClosureWhichReturnsAnInt()) // Invocation happens now here
>>>>>
>>>>> return is scope based and it’s totally clear (to me) that in your case return will return from your closure with a value of Void.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Adrian Zubarev
>>>>> Sent with Airmail
>>>>>
>>>>> Am 15. März 2017 um 11:35:39, Rien via swift-evolution (swift-evolution at swift.org) schrieb:
>>>>>
>>>>>> What does the following code fragment do?
>>>>>>
>>>>>> serverCert.write(to: certificateUrl) { showErrorInKeyWindow(message); return }
>>>>>>
>>>>>> The only possible answer is: I don’t know.
>>>>>>
>>>>>> The problem is finding out what the “return” statement will do.
>>>>>>
>>>>>> Without knowing if the {...} is a code block or a trailing closure it is impossible to know what the return statement will do. It will either end the closure or it will end the function that contains this code block.
>>>>>>
>>>>>> This could be disambiguated by using the same syntax as for lazy variables:
>>>>>>
>>>>>> serverCert.write(to: serverCertificateUrl) { showErrorInKeyWindow(message: message); return }()
>>>>>>
>>>>>> Now it is clear that the return statement will only terminate the (trailing) closure.
>>>>>>
>>>>>> A question to the educators on the list: Is this a real problem?
>>>>>>
>>>>>> Personally, I dislike this situation, but I am also ambivalent towards the solution I just described.
>>>>>>
>>>>>> Regards,
>>>>>> Rien
>>>>>>
>>>>>> Site: http://balancingrock.nl
>>>>>> Blog: http://swiftrien.blogspot.com
>>>>>> Github: http://github.com/Balancingrock
>>>>>> Project: http://swiftfire.nl
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> swift-evolution at swift.org
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
More information about the swift-evolution
mailing list