[swift-evolution] Making capturing semantics of local functions explicit

Johannes Weiß johannesweiss at apple.com
Thu Oct 26 05:29:01 CDT 2017


Hi,

> On 25 Oct 2017, at 6:01 pm, John McCall via swift-evolution <swift-evolution at swift.org> wrote:
> 
>> On Oct 25, 2017, at 7:41 AM, David Hart via swift-evolution <swift-evolution at swift.org> wrote:
>> I got bit again by a sneaky memory leak concerning local functions and would like to discuss a small language change. I vaguely remember this being discussed in the past, but can’t find the thread (if anybody could point me to it, I’d appreciate it). Basically, here’s an example of the leak:
>> 
>> class A
>>  {
>>     
>> func foo
>> () {
>>         
>> func local
>> () {
>>             
>> bar
>> ()
>>         }
>>     
>>         methodWithEscapingClosure { [
>> unowned self] _ in
>> 
>>             
>> self.bar
>> ()
>>             
>> local() // this leaks because local captures self
>>         }
>>     }
>>     
>>     
>> func bar
>> () {
>>     }
>> }
>> 
>> 
>> Its sneaky because local’s capturing of self is not obvious if you’ve trained your brain to watch out for calls prefixed with self. I would suggest having the compiler force users to make self capturing explicit, the same way it does for closures:
> 
> I think this is a good idea.  Ideally the proposal would also allow explicit capture lists in local functions.

Yes, please. Optionally allowing exhaustive capture lists would be great. I think they work really well as compiler checked documentation too.
Sometimes a programmer makes sure that a given closure doesn't capture something and maybe even adds a comment explaining that and why this might be important. Still, it's fairly easy for another programmer to accidentally capture something without even noticing. And given that we mostly review on diffs with limited context it's even possible that this change slips though the review as the comment doesn't necessarily appear in the review.

With optional exhaustive capture lists, this problem would go away because a) a programmer is more likely to think about the consequences when changing the capture list b) it's obvious in code review.
That's especially true if capture lists are optional because the mere fact that there is a capture list suggests that the code might rely on the very captures only.

-- Johannes


> 
> John.
> 
>> 
>> class A
>>  {
>>     
>> func foo
>> () {
>>         
>> func local
>> () {
>>             
>> bar
>> () // error: Call to method ‘bar' in function ‘local' requires explicit 'self.' to make capture semantics explicit
>>         }
>>     
>> 
>> 	
>> // ...
>>     }
>> }
>> 
>> 
>> What do you think?
>> 
>> David.
>> 
>> _______________________________________________
>> 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