> On Mar 16, 2016, at 11:09 AM, Jordan Rose via swift-evolution > <[email protected]> wrote: > > It's worth noting that—for better or for worse—explicit capture has different > semantics from implicit capture today. If a local variable ('var', not 'let') > is captured, it is captured by value when mentioned explicitly and by > reference when not. This is discussed in The Swift Programming Language > <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/doc/uid/TP40014097-CH32-ID544>. > > If you were to then propose a syntax of `inout x` or `&x`, I would argue that > there is no inout-ish behavior: updates to the variable both inside and > outside the closure (a) are always reflected immediately (i.e. there is no > writeback), and (b) are not subject to the aliasing restrictions that 'inout' > has. > > (Not that I have an alternative spelling handy.)
`[var x]` seems to me like a reasonable spelling for explicit `var` capture. -Joe > > Jordan > > >> On Mar 13, 2016, at 19:12, Daniel Duan via swift-evolution >> <[email protected] <mailto:[email protected]>> wrote: >> >> I'm curious to see if anyone else has desire for this change. >> >> Currently, scopes created by functions, closures, "do {}", etc. >> implicitly capture values from their outer scopes. The only way to opt out >> this behavior is via functions defined "elsewhere": >> >> func a() { ... } >> func foo(b: () -> ()) { >> func c() { ... } >> let d = { ... } >> >> a() // nothing from foo's scope will implicitly get into a >> b() // nothing from foo's scope will implicitly get into b >> >> c() // implicitly captures values in foo >> d() // implicitly captures values in foo >> do { >> // implicitly captures values in foo >> } >> } >> >> One problem that comes with this bebavior is unintended capturing. E.g. a >> user >> may think they successfuly factored out some code, but a missing variable was >> satified by something with the same name from an outer scope. >> >> C++ addresses this issue by making its user explicitly indicate lambda's >> capturing behavior: >> >> [] {...} // capture nothing >> [=] {...} // capture everything by value >> [&] {...} // capture everything by reference >> >> It'd be nice if Swift can allow user to opt out the automatic capturing at >> some level. We already have the capture list syntax, reusing it for explictly >> capture in this case: >> >> func foo() { >> let a = 5 >> let b = "Ziggy" >> let c = ["Weild", "Gilly"] >> >> let d: @explicit_capture () -> () = { [a, b] in >> let years = a // ok >> let artist = b // ok >> let others = c // error: implicit capture in not allowed for 'd' >> } >> } >> >> >> An alternative would be making implicit capture an opt-in feature (similar to >> C++): >> >> func foo() { >> let a = 5 >> let b = "Ziggy" >> let c = ["Weild", "Gilly"] >> >> let d = { [a] in >> let years = a // ok >> let artist = b // error: implicit capture in not allowed for 'd' >> let others = c // error: implicit capture in not allowed for 'd' >> } >> >> let e: @capture_all () -> () = { [a] in >> let years = a // ok >> let artist = b // ok >> let others = c // error: implicit capture in not allowed for 'e' >> } >> } >> >> Obviously, this version would be a breaking change. >> >> I have no attchment to the syntax. Chris has brought up moving @noescape >> before variable types declaration, so putting @explicit_capture there seems >> natural. >> >> Thoughts? >> _______________________________________________ >> swift-evolution mailing list >> [email protected] <mailto:[email protected]> >> https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
