[swift-evolution] [Pitch] Improving capturing semantics of local functions

David Hart david at hartbit.com
Mon Nov 13 15:30:25 CST 2017



> On 13 Nov 2017, at 05:52, Slava Pestov <spestov at apple.com> wrote:
> 
> 
> 
>> On Nov 12, 2017, at 8:11 PM, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>>> On Nov 12, 2017, at 12:55 AM, David Hart via swift-evolution <swift-evolution at swift.org> wrote:
>>> 
>>> 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
>> 
>> 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.

> Slava
> 
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171113/7da8467a/attachment.html>


More information about the swift-evolution mailing list