# \[Pitch\] Improving capturing semantics of local functions

**URL:** <https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054>\
**Category:** Pitches\
**Created:** [November 12, 2017, 8:55am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054 "2017-11-12T08:55:02Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![hartbit](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hartbit/32/738_2.png) [@hartbit](https://forums.swift.org/u/hartbit)\
**Post date:** [November 12, 2017, 8:55am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/1 "2017-11-12T08:55:02Z")

</div>

Hello evolution folks,

After the positive feedback on the idea of improving capturing semantics of local functions, Alex Lynch and I worked on a proposal. Please let us know if you have any feedback:

> <https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/XXXX-improve-capture-semantics-of-local-functions.md>

We’re also looking for help in implementing it. Please let us know!

David.

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [November 12, 2017, 11:26am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/2 "2017-11-12T11:26:56Z")

</div>

Imho it’s good to copy the concept of capture lists — but it could be done differently, without polluting the body:  
func foo[capture list](parameters) {}  
I’m not sure if there are corner cases with subscript-syntax, but in general, I think this approach is nicer.

- Tino

---

<div class="post-metadata">

**Author:** ![Brent\_Royal-Gordon](https://avatars.discourse-cdn.com/v4/letter/b/53a042/32.png) [@Brent\_Royal-Gordon](https://forums.swift.org/u/Brent_Royal-Gordon)\
**Post date:** [November 13, 2017, 4:11am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/3 "2017-11-13T04:11:29Z")

</div>

> Hello evolution folks,
> 
> After the positive feedback on the idea of improving capturing semantics of local functions, Alex Lynch and I worked on a proposal. Please let us know if you have any feedback:
> 
> [https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/XXXX-improve-capture-semantics-of-local-functions.md](https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/XXXX-improve-capture-semantics-of-local-functions.md)

So, quoting the proposal:

> First of all, this proposal suggests extending the requirement of the self. prefix to local functions, but only if the local function is used as or used inside an escaping closure.

I don't love that the use of a function many lines away can cause errors in that closure. There's a "spooky action-at-a-distance" quality to this behavior that I don't like.

The best idea I have is to require local functions to be annotated with `@escaping` if they're to be used in an escaping closure:

&nbsp;&nbsp;&nbsp;&nbsp;func foo() {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// `local1` is nonescaping since it isn't marked with the @escaping attribute.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func local1() {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bar()  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local1() // OK, direct call  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ local1() }() // OK, closure is nonescaping  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async(execute: local1) // error: passing non-escaping function 'local2' to function expecting an @escaping closure  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async { local1() } // error: closure use of non-escaping function 'local2' may allow it to escape

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@escaping func local2() {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bar() // error: call to method 'bar' in escaping local function requires explicit 'self.' to make capture semantics explicit  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@escaping func local3() {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self. bar() // OK, explicit `self`  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async(execute: local3) // OK, escaping function  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async { local3() } // OK, escaping closure  
&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;func bar() {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print("bar")  
&nbsp;&nbsp;&nbsp;&nbsp;}

But this would be quite source-breaking. (Maybe it could be introduced as a warning first?)

> Secondly, this proposal suggests allowing the same capture list syntax from closures in local functions. Capture lists would still be invalid in top-level and member functions.

I think this is a good idea, but I don't like bringing the already weird use of `in` to actual functions.

By analogy with the current closure syntax, the capture list ought to go somewhere before the parameter list, in one of these slots:

1. func fn\<T\>[foo, bar](param: T) throws -\> T where T: Equatable { … }  
2. func fn[foo, bar]\<T\>(param: T) throws -\> T where T: Equatable { … }  
3. func [foo, bar] fn\<T\>(param: T) throws -\> T where T: Equatable { … }  
4. [foo, bar] func fn\<T\>(param: T) throws -\> T where T: Equatable { … }

Of these options, I actually think #4 reads best; 1 and 2 are very cluttered, and 3 just seems weird. But it seems like the one that would be easiest to misparse.

> **···**
>
> > On Nov 12, 2017, at 12:55 AM, David Hart via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> --  
> Brent Royal-Gordon  
> Architechies

---

<div class="post-metadata">

**Author:** ![ckeithray](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ckeithray/32/2317_2.png) [@ckeithray](https://forums.swift.org/u/ckeithray)\
**Post date:** [November 13, 2017, 4:37am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/4 "2017-11-13T04:37:31Z")

</div>

I'd vote for # 1

Starting with "func" helps signal that the context is a function. (Though I know some things can precede "func".)

Having the function name second is important to me: you don't have to scan further for its name.

Template arguments seem more important than capture lists, so I'd put it before the other.

> **···**
>
> --  
> C. Keith Ray
> 
> \* [What Every Programmer Needs To… by C. Keith Ray [PDF/iPad/Kindle]](https://leanpub.com/wepntk) \<- buy my book?  
> \* [http://www.thirdfoundationsw.com/keith\_ray\_resume\_2014\_long.pdf](http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf)  
> \* [http://agilesolutionspace.blogspot.com/](http://agilesolutionspace.blogspot.com/)
> 
> > On Nov 12, 2017, at 8:11 PM, Brent Royal-Gordon via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > 1. func fn\<T\>[foo, bar](param: T) throws -\> T where T: Equatable { … }  
> > 2. func fn[foo, bar]\<T\>(param: T) throws -\> T where T: Equatable { … }  
> > 3. func [foo, bar] fn\<T\>(param: T) throws -\> T where T: Equatable { … }  
> > 4. [foo, bar] func fn\<T\>(param: T) throws -\> T where T: Equatable { … }

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [November 13, 2017, 4:52am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/5 "2017-11-13T04:52:28Z")

</div>

> > Hello evolution folks,
> > 
> > After the positive feedback on the idea of improving capturing semantics of local functions, Alex Lynch and I worked on a proposal. Please let us know if you have any feedback:
> > 
> > [https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/XXXX-improve-capture-semantics-of-local-functions.md](https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/XXXX-improve-capture-semantics-of-local-functions.md)
> 
> So, quoting the proposal:
> 
> > First of all, this proposal suggests extending the requirement of the self. prefix to local functions, but only if the local function is used as or used inside an escaping closure.
> 
> I don't love that the use of a function many lines away can cause errors in that closure. There's a "spooky action-at-a-distance" quality to this behavior that I don't like.

Agreed.

> I think this is a good idea, but I don't like bringing the already weird use of `in` to actual functions.
> 
> By analogy with the current closure syntax, the capture list ought to go somewhere before the parameter list, in one of these slots:
> 
> 1. func fn\<T\>[foo, bar](param: T) throws -\> T where T: Equatable { … }  
> 2. func fn[foo, bar]\<T\>(param: T) throws -\> T where T: Equatable { … }  
> 3. func [foo, bar] fn\<T\>(param: T) throws -\> T where T: Equatable { … }  
> 4. [foo, bar] func fn\<T\>(param: T) throws -\> T where T: Equatable { … }
> 
> Of these options, I actually think #4 reads best; 1 and 2 are very cluttered, and 3 just seems weird. But it seems like the one that would be easiest to misparse.

Another option that reads nicely IMHO is

func fn\<T\>(param: T) throws -\> T where T : Equatable [foo, bar] { … }

I think #4 is ambiguous with array literals unfortunately.

Perhaps this proposal should be split in two — the ‘self.’/escaping part is source breaking, and will likely require more discussion. Adding capture lists to local functions seems like a more straightforward change.

Slava

> **···**
>
> > On Nov 12, 2017, at 8:11 PM, Brent Royal-Gordon via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > > On Nov 12, 2017, at 12:55 AM, David Hart via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> > --  
> > Brent Royal-Gordon  
> > Architechies
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [November 13, 2017, 9:17am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/6 "2017-11-13T09:17:36Z")

</div>

> > Hello evolution folks,
> > 
> > After the positive feedback on the idea of improving capturing semantics of local functions, Alex Lynch and I worked on a proposal. Please let us know if you have any feedback:
> > 
> > [https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/XXXX-improve-capture-semantics-of-local-functions.md](https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/XXXX-improve-capture-semantics-of-local-functions.md)
> 
> So, quoting the proposal:
> 
> > First of all, this proposal suggests extending the requirement of the self. prefix to local functions, but only if the local function is used as or used inside an escaping closure.
> 
> I don't love that the use of a function many lines away can cause errors in that closure. There's a "spooky action-at-a-distance" quality to this behavior that I don't like.
> 
> The best idea I have is to require local functions to be annotated with `@escaping` if they're to be used in an escaping closure:
> 
> &nbsp;&nbsp;&nbsp;func foo() {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// `local1` is nonescaping since it isn't marked with the @escaping attribute.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func local1() {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bar()  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local1() // OK, direct call  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ local1() }() // OK, closure is nonescaping  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async(execute: local1) // error: passing non-escaping function 'local2' to function expecting an @escaping closure  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async { local1() } // error: closure use of non-escaping function 'local2' may allow it to escape
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@escaping func local2() {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bar() // error: call to method 'bar' in escaping local function requires explicit 'self.' to make capture semantics explicit  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@escaping func local3() {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self. bar() // OK, explicit `self`  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async(execute: local3) // OK, escaping function  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async { local3() } // OK, escaping closure  
> &nbsp;&nbsp;}
> 
> &nbsp;&nbsp;&nbsp;func bar() {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print("bar")  
> &nbsp;&nbsp;&nbsp;}
> 
> But this would be quite source-breaking. (Maybe it could be introduced as a warning first?)

I like the idea of requiring @escaping to be explicit on local funcs, but I'm worried that it might be too onerous; after all, we infer @escapingness on closures quite successfully. At the same time, I agree that applying semantic rules based on how the func is used, potentially much later in the function, is really spooky. I don't have a great alternative right now.

Random note: we currently infer non-escapingness for local funcs that capture ``inout``s, since those cannot be allowed to escape. In fact, this is the only way to make a local function non-escaping at all.

John.

> **···**
>
> > On Nov 12, 2017, at 11:11 PM, Brent Royal-Gordon via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > > On Nov 12, 2017, at 12:55 AM, David Hart via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> > > Secondly, this proposal suggests allowing the same capture list syntax from closures in local functions. Capture lists would still be invalid in top-level and member functions.
> > 
> > I think this is a good idea, but I don't like bringing the already weird use of `in` to actual functions.
> > 
> > By analogy with the current closure syntax, the capture list ought to go somewhere before the parameter list, in one of these slots:
> > 
> > 1. func fn\<T\>[foo, bar](param: T) throws -\> T where T: Equatable { … }  
> > 2. func fn[foo, bar]\<T\>(param: T) throws -\> T where T: Equatable { … }  
> > 3. func [foo, bar] fn\<T\>(param: T) throws -\> T where T: Equatable { … }  
> > 4. [foo, bar] func fn\<T\>(param: T) throws -\> T where T: Equatable { … }
> > 
> > Of these options, I actually think #4 reads best; 1 and 2 are very cluttered, and 3 just seems weird. But it seems like the one that would be easiest to misparse.
> > 
> > --  
> > Brent Royal-Gordon  
> > Architechies
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner](https://avatars.discourse-cdn.com/v4/letter/c/bc8723/32.png) [@Chris\_Lattner](https://forums.swift.org/u/Chris_Lattner)\
**Post date:** [November 21, 2017, 2:59am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/7 "2017-11-21T02:59:21Z")

</div>

This is relatively rare, so I’d suggest introducing a context sensitive keyword to make it explicit, perhaps:

5. func fn\<T\>[foo, bar](param: T) throws -\> T where T: Equatable captures [foo, bar] { … }

It makes sense (IMO) to keep it near the body of the function, since it is more an artifact of the implementation than it is about the API. Yes I know that caring about the API of a local function is weird :-)

-Chris

> **···**
>
> > On Nov 12, 2017, at 8:11 PM, Brent Royal-Gordon via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > > Secondly, this proposal suggests allowing the same capture list syntax from closures in local functions. Capture lists would still be invalid in top-level and member functions.
> > 
> > I think this is a good idea, but I don't like bringing the already weird use of `in` to actual functions.
> > 
> > By analogy with the current closure syntax, the capture list ought to go somewhere before the parameter list, in one of these slots:
> > 
> > 1. func fn\<T\>[foo, bar](param: T) throws -\> T where T: Equatable { … }  
> > 2. func fn[foo, bar]\<T\>(param: T) throws -\> T where T: Equatable { … }  
> > 3. func [foo, bar] fn\<T\>(param: T) throws -\> T where T: Equatable { … }  
> > 4. [foo, bar] func fn\<T\>(param: T) throws -\> T where T: Equatable { … }
> > 
> > Of these options, I actually think #4 reads best; 1 and 2 are very cluttered, and 3 just seems weird. But it seems like the one that would be easiest to misparse.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [November 21, 2017, 11:07pm UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/8 "2017-11-21T23:07:27Z")

</div>

> > Hello evolution folks,
> > 
> > After the positive feedback on the idea of improving capturing semantics of local functions, Alex Lynch and I worked on a proposal. Please let us know if you have any feedback:
> > 
> > [https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/XXXX-improve-capture-semantics-of-local-functions.md](https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/XXXX-improve-capture-semantics-of-local-functions.md)
> 
> So, quoting the proposal:
> 
> > First of all, this proposal suggests extending the requirement of the self. prefix to local functions, but only if the local function is used as or used inside an escaping closure.
> 
> I don't love that the use of a function many lines away can cause errors in that closure. There's a "spooky action-at-a-distance" quality to this behavior that I don't like.

I could go either way on that. Especially since if you want to find out where the escaping references are, you could just remove the @escaping annotation (below) and look for the compiler errors.

> The best idea I have is to require local functions to be annotated with `@escaping` if they're to be used in an escaping closure:
> 
> &nbsp;&nbsp;&nbsp;func foo() {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// `local1` is nonescaping since it isn't marked with the @escaping attribute.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func local1() {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bar()  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local1() // OK, direct call  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ local1() }() // OK, closure is nonescaping  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async(execute: local1) // error: passing non-escaping function 'local2' to function expecting an @escaping closure  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async { local1() } // error: closure use of non-escaping function 'local2' may allow it to escape
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@escaping func local2() {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bar() // error: call to method 'bar' in escaping local function requires explicit 'self.' to make capture semantics explicit  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@escaping func local3() {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self. bar() // OK, explicit `self`  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async(execute: local3) // OK, escaping function  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchQueue.main.async { local3() } // OK, escaping closure  
> &nbsp;&nbsp;}
> 
> &nbsp;&nbsp;&nbsp;func bar() {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print("bar")  
> &nbsp;&nbsp;&nbsp;}
> 
> But this would be quite source-breaking. (Maybe it could be introduced as a warning first?)

+1

> > Secondly, this proposal suggests allowing the same capture list syntax from closures in local functions. Capture lists would still be invalid in top-level and member functions.
> 
> I think this is a good idea, but I don't like bringing the already weird use of `in` to actual functions.
> 
> By analogy with the current closure syntax, the capture list ought to go somewhere before the parameter list, in one of these slots:
> 
> 1. func fn\<T\>[foo, bar](param: T) throws -\> T where T: Equatable { … }  
> 2. func fn[foo, bar]\<T\>(param: T) throws -\> T where T: Equatable { … }  
> 3. func [foo, bar] fn\<T\>(param: T) throws -\> T where T: Equatable { … }  
> 4. [foo, bar] func fn\<T\>(param: T) throws -\> T where T: Equatable { … }
> 
> Of these options, I actually think #4 reads best; 1 and 2 are very cluttered, and 3 just seems weird. But it seems like the one that would be easiest to misparse.

We should keep capture lists where they are (in the body). Currently functions and closures have very similar syntax:

func doSomething(section: Int, value: Double) -\> String { … }

var doSomething: (\_ section: Int, \_ value: Double) -\> String { [captures…] s,v in }

So you basically need to replace “func” with “var”, copy your parameter names in to the body and replace them with underscores (because closure types can’t have argument labels — I think the core team do want to add those add some point IIRC… ). I don’t see a good reason to force developers to also shuffle their capture lists around. When you’re working with local functions, it’s hard enough to style your code so that you keep within your column-limit. It can be delicate, is what I’m saying.

- Karl

> **···**
>
> > On 13. Nov 2017, at 05:11, Brent Royal-Gordon via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > > On Nov 12, 2017, at 12:55 AM, David Hart via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> > --  
> > Brent Royal-Gordon  
> > Architechies
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![ckeithray](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ckeithray/32/2317_2.png) [@ckeithray](https://forums.swift.org/u/ckeithray)\
**Post date:** [November 13, 2017, 5:00am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/9 "2017-11-13T05:00:35Z")

</div>

> Another option that reads nicely IMHO is
> 
> func fn\<T\>(param: T) throws -\> T where T : Equatable [foo, bar] { … }

I changed my mind. Putting the capture list just before { } is where I'd rather see it.

> **···**
>
> > I think #4 is ambiguous with array literals unfortunately.
> > 
> > Perhaps this proposal should be split in two — the ‘self.’/escaping part is source breaking, and will likely require more discussion. Adding capture lists to local functions seems like a more straightforward change.
> > 
> > Slava
> > 
> > > --  
> > > Brent Royal-Gordon  
> > > Architechies
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![hartbit](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hartbit/32/738_2.png) [@hartbit](https://forums.swift.org/u/hartbit)\
**Post date:** [November 13, 2017, 9:30pm UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/10 "2017-11-13T21:30:25Z")

</div>

> > > Hello evolution folks,
> > > 
> > > After the positive feedback on the idea of improving capturing semantics of local functions, Alex Lynch and I worked on a proposal. Please let us know if you have any feedback:
> > > 
> > > [https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/XXXX-improve-capture-semantics-of-local-functions.md](https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/XXXX-improve-capture-semantics-of-local-functions.md)
> > 
> > So, quoting the proposal:
> > 
> > > First of all, this proposal suggests extending the requirement of the self. prefix to local functions, but only if the local function is used as or used inside an escaping closure.
> > 
> > I don't love that the use of a function many lines away can cause errors in that closure. There's a "spooky action-at-a-distance" quality to this behavior that I don't like.
> 
> Agreed.

Thanks Brent, Slava and John for your feedback. I think you are right: I picked up the idea from the original thread because it would reduce source breakage, but I’m starting to thing its just not worth it.

Concerning the alternative solution of annotating local functions with @escaping, it’s definitely an interesting idea. It might be slightly more source-breaking but, as mentioned in the proposal, the breakage will attract attention to code where its easy to unknowingly create memory leaks.

> > I think this is a good idea, but I don't like bringing the already weird use of `in` to actual functions.
> > 
> > By analogy with the current closure syntax, the capture list ought to go somewhere before the parameter list, in one of these slots:
> > 
> > 1. func fn\<T\>[foo, bar](param: T) throws -\> T where T: Equatable { … }  
> > 2. func fn[foo, bar]\<T\>(param: T) throws -\> T where T: Equatable { … }  
> > 3. func [foo, bar] fn\<T\>(param: T) throws -\> T where T: Equatable { … }  
> > 4. [foo, bar] func fn\<T\>(param: T) throws -\> T where T: Equatable { … }
> > 
> > Of these options, I actually think #4 reads best; 1 and 2 are very cluttered, and 3 just seems weird. But it seems like the one that would be easiest to misparse.
> 
> Another option that reads nicely IMHO is
> 
> func fn\<T\>(param: T) throws -\> T where T : Equatable [foo, bar] { … }
> 
> I think #4 is ambiguous with array literals unfortunately.

This is pure aesthetics, but I’m a bit bothered by all 5 options. Local functions and closures are syntactically different enough that we can either choose to keep capture lists in the same position relative to the curly braces (like I proposed), or relative to the parameters (like Brent proposes). Don’t you think that the suggestion in the pitch is the least confusing for users? On a side note, Slava’s 5th option seems like its breaking relative position with the curly braces and the parameters.

> Perhaps this proposal should be split in two — the ‘self.’/escaping part is source breaking, and will likely require more discussion. Adding capture lists to local functions seems like a more straightforward change.

Seems like a good idea. Once we all come close to an agreement, Alex and I can spit them into two proposals.

David.

> **···**
>
> > On 13 Nov 2017, at 05:52, Slava Pestov \<spestov@apple.com\> wrote:
> > 
> > > On Nov 12, 2017, at 8:11 PM, Brent Royal-Gordon via swift-evolution \<swift-evolution@swift.org\> wrote:
> > > 
> > > > On Nov 12, 2017, at 12:55 AM, David Hart via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> > Slava
> > 
> > > --  
> > > Brent Royal-Gordon  
> > > Architechies
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner](https://avatars.discourse-cdn.com/v4/letter/c/bc8723/32.png) [@Chris\_Lattner](https://forums.swift.org/u/Chris_Lattner)\
**Post date:** [November 21, 2017, 3:00am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/11 "2017-11-21T03:00:19Z")

</div>

> func fn\<T\>(param: T) throws -\> T where T : Equatable [foo, bar] { … }

+1, potentially adding a context sensitive keyword like “capturing” before it.

> I think #4 is ambiguous with array literals unfortunately.
> 
> Perhaps this proposal should be split in two — the ‘self.’/escaping part is source breaking, and will likely require more discussion. Adding capture lists to local functions seems like a more straightforward change.

+1.

-Chris

> **···**
>
> > On Nov 12, 2017, at 8:52 PM, Slava Pestov via swift-evolution \<swift-evolution@swift.org\> wrote:

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [November 21, 2017, 10:06am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/12 "2017-11-21T10:06:04Z")

</div>

> 5. func fn\<T\>[foo, bar](param: T) throws -\> T where T: Equatable captures [foo, bar] { … }

I guess it can be considered good practice to start a line with the most important information, and move the details to the far right, so that they don’t distract the hasty reader.  
I’m not sure if the capture list an example for this, but for good or worse, it didn’t draw much attention in another position either (the first „[foo, bar]“ that slipped through).

That variant (func fn\<T\>[foo, bar](param: T)) is definitely my favorite, because it keeps a characteristic of closures (first the capture list, then the parameters), but doesn’t carry over the mingling of body and parameters that has to be done in closures.

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [November 13, 2017, 10:03pm UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/13 "2017-11-13T22:03:02Z")

</div>

I think it would be unfortunate to have the capture list before the template parameters:  
Template parameters might be used in the capture list, and although Swift doesn’t rely on strict „linearity“ or forward declarations, I don’t want to be forced to use things that aren’t declared yet.

---

<div class="post-metadata">

**Author:** ![trs](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/trs/32/2038_2.png) [@trs](https://forums.swift.org/u/trs)\
**Post date:** [November 21, 2017, 5:50am UTC](https://forums.swift.org/t/pitch-improving-capturing-semantics-of-local-functions/7054/14 "2017-11-21T05:50:51Z")

</div>

> > func fn\<T\>(param: T) throws -\> T where T : Equatable [foo, bar] { … }
> 
> +1, potentially adding a context sensitive keyword like “capturing” before it.

+1 including the keyword "capturing"

-Thorsten

> **···**
>
> > Am 21.11.2017 um 04:00 schrieb Chris Lattner via swift-evolution \<swift-evolution@swift.org\>:
> > 
> > > On Nov 12, 2017, at 8:52 PM, Slava Pestov via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> > > I think #4 is ambiguous with array literals unfortunately.
> > > 
> > > Perhaps this proposal should be split in two — the ‘self.’/escaping part is source breaking, and will likely require more discussion. Adding capture lists to local functions seems like a more straightforward change.
> > 
> > +1.
> > 
> > -Chris
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
