[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