Am 27.06.2016 20:55, schrieb Christopher Kornher:
On Jun 27, 2016, at 2:45 AM, Manuel Krebber via swift-evolution <swift-evolution@swift.org> wrote:

On 06/26/2016 09:10 PM, Christopher Kornher via swift-evolution wrote:
The core proposal:
——————

Closures capturing object references should automatically capture all
object references as weak.
In my code, most closures are used in a functional programming capacity, e.g. with map(), reduce, etc. Hence, most closures are non-escaping and
local, where strong capture is the desired way. Otherwise I would have
to litter everything with optional unwrapping or add the explicit
capture definition which would both make the code less readable in my
opinion.

I thought about this some more and it makes sense to treat
non-escaping closures are they are treated now. This might increase
the burden on the compiler especially because these closures may not
be declared inline. This would be far more straightforward than having
to worry about changes to object existence within one or more
invocations of a @nonescaping closure, especially in multi-threaded
code.

I do not think that this would be a significant change for developers
in practice. Any developer who would try to rely upon object
references changing within the application of a @nonescaping closure
would probably have read the manual very carefully :)



I am unsure whether treating closures differently depending on a @nonescaping attribute on a function is a good idea. The problem is that, theoretically, the closure might be stored in a variable or used with different functions. Then how do you decide whether the default is strong or weak capture?

Example:

func f1(_ f : (Int) -> Int) {
...
}

func f2(_ f : @noescape  (Int) -> Int) {
...
}

let foo = Foo()
let f : (Int) -> Int = {
  return foo.x
}

f1(f)
f2(f)

In addition different default capture behaviour dependant on context could be confusing for developers I think.

1) Closures with object references could be simplified further by
implicitly including ‘let’ guards for all object references:
This sounds good for closures without return value, but how would you
handle closures with non-optional non-void return values?

Good point.

1) The simplest solution would be to have these closures require
capture lists to some or all object references. Given the prevalence
of the weak/strong dance, calling these out in some way probably
should be done anyway.

2) Another option would be to eliminate the implicit nil check guards,
making all object references optional. The compiler would force these
to be unwrapped, so users would be guided to do the right thing.

3) Just always weakly capturing all object references would treat all
closures uniformly.


I think I favour 2) out of these, even though it still means the code will potentially be littered with ?. or let guards...

Kind regards, Manuel

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

Reply via email to