> 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:
>> 
>> 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.
> 

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:
> 
>    func foo() {
>        // `local1` is nonescaping since it isn't marked with the @escaping 
> attribute.
>        func local1() {
>            bar()
>        }
>        local1()               // OK, direct call
>        { local1() }() // OK, closure is nonescaping
>        DispatchQueue.main.async(execute: local1)      // error: passing 
> non-escaping function 'local2' to function expecting an @escaping closure
>        DispatchQueue.main.async { local1() }          // error: closure use 
> of non-escaping function 'local2' may allow it to escape
> 
>        @escaping func local2() {
>            bar()              // error: call to method 'bar' in escaping 
> local function requires explicit 'self.' to make capture semantics explicit
>        }
> 
>        @escaping func local3() {
>           self. bar() // OK, explicit `self`
>        }
>        DispatchQueue.main.async(execute: local3)      // OK, escaping function
>        DispatchQueue.main.async { local3() }          // OK, escaping closure
>   }
> 
>    func bar() {
>        print("bar")
>    }
> 
> 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

> -- 
> Brent Royal-Gordon
> Architechies
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to