[swift-evolution] Proposal: Closures capture weak by default
ilya
ilya.nikokoshev at gmail.com
Tue Dec 8 06:08:03 CST 2015
I don't think this would satisfy the principle of "working as expected",
e.g.:
class Computer {
func compute() -> Int { ... }
}
func test() {
let c = Computer()
// Expected: the closure executes in the background
dispatch_async(...) {
let computed = c.compute()
print(computed)
let computed2 = c.compute()
print(computed2)
}
}
Actual result if the proposal passes: the closure will not compile as c
will be optional.
Moreover, you'll have some beginners who will fix it with
dispatch_async(...) {
if let computed = c?.compute() {
print(computed)
}
if let computed2 = c?.compute() {
print(computed2)
}
}
which has entirely different logic, as now any of those situations is
possible:
(1) both computed and computed2 are printed
(2) none of those is printed
(3) only computed is printed
On Tue, Dec 8, 2015 at 14:15 Andrew Bennett via swift-evolution <
swift-evolution at swift.org> wrote:
> From https://swift.org/about/: "The most obvious way to write code should
> also behave in a safe manner."
>
> To this end I think that closures should capture references types weakly
> by default. Pretty much the only way I know of to (easily) create memory
> issues with pure swift is to capture a strong reference in a closure.
>
> I think with consideration when designing asynchronous APIs this could be
> quite painless.
>
> Cases weak may be excluded:
> * If the closure is @noescape
> * If the object's lifetime is provably limited to the block
> * If it's a value type
>
> I think the upsides by far outweigh the downsides.
>
> Upside:
> * no more surprises
> * safer code
>
> Downsides:
> * You may sometimes have to use optional chaining or similar to resolve a
> weak reference.
> * Beginners need to understand optionals, but they're likely to do so
> before learning blocks.
> * There's probably a few edge cases I haven't explored, and a few more
> here:
>
> class Test {
> func doSomething(v: Int) { ... }
> func async(callback: Int->Void) {
> doWork { value in
> callback?(value)
> }
> }
> }
>
> self.test = Test()
> self.test.async(test.doSomething) // what is the lifetime
> of test.doSomething?
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151208/c4a76f6e/attachment.html>
More information about the swift-evolution
mailing list