<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">It's worth noting that—for better or for worse—explicit capture has different semantics from implicit capture today. If a local <i class="">variable</i>&nbsp;('var', not 'let') is captured, it is captured by value when mentioned explicitly and by reference when not. This is&nbsp;<a href="https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/doc/uid/TP40014097-CH32-ID544" class="">discussed in The Swift Programming Language</a>.</div><div class=""><br class=""></div><div class="">If you were to then propose a syntax of `inout x` or `&amp;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.&nbsp;</div><div class=""><br class=""></div><div class="">(Not that I have an alternative spelling handy.)</div><div class=""><br class=""></div><div class="">Jordan</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 13, 2016, at 19:12, Daniel Duan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">I'm curious to see if anyone else has desire for this change.<br class=""><br class="">Currently, scopes created by functions, closures, "do {}", etc.<br class="">implicitly capture values from their outer scopes. The only way to opt out<br class="">this behavior is via functions defined "elsewhere":<br class=""><br class="">func a() { ... }<br class="">func foo(b: () -&gt; ()) {<br class=""> &nbsp;&nbsp;&nbsp;func c() { ... }<br class=""> &nbsp;&nbsp;&nbsp;let d = { ... }<br class=""><br class=""> &nbsp;&nbsp;&nbsp;a() // nothing from foo's scope will implicitly get into a<br class=""> &nbsp;&nbsp;&nbsp;b() // nothing from foo's scope will implicitly get into b<br class=""><br class=""> &nbsp;&nbsp;&nbsp;c() // implicitly captures values in foo<br class=""> &nbsp;&nbsp;&nbsp;d() // implicitly captures values in foo<br class=""> &nbsp;&nbsp;&nbsp;do {<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// implicitly captures values in foo<br class=""> &nbsp;&nbsp;&nbsp;}<br class="">}<br class=""><br class="">One problem that comes with this bebavior is unintended capturing. E.g. a user<br class="">may think they successfuly factored out some code, but a missing variable was<br class="">satified by something with the same name from an outer scope.<br class=""><br class="">C++ addresses this issue by making its user explicitly indicate lambda's<br class="">capturing behavior:<br class=""><br class="">[] {...} &nbsp;// capture nothing<br class="">[=] {...} &nbsp;// capture everything by value<br class="">[&amp;] {...} &nbsp;// capture everything by reference<br class=""><br class="">It'd be nice if Swift can allow user to opt out the automatic capturing at<br class="">some level. We already have the capture list syntax, reusing it for explictly<br class="">capture in this case:<br class=""><br class="">func foo() {<br class=""> &nbsp;&nbsp;&nbsp;let a = 5<br class=""> &nbsp;&nbsp;&nbsp;let b = "Ziggy"<br class=""> &nbsp;&nbsp;&nbsp;let c = ["Weild", "Gilly"]<br class=""><br class=""> &nbsp;&nbsp;&nbsp;let d: @explicit_capture () -&gt; () = { [a, b] in<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let years = a // ok<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let artist = b // ok<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let others = c // error: implicit capture in not allowed for 'd'<br class=""> &nbsp;&nbsp;&nbsp;}<br class="">}<br class=""><br class=""><br class="">An alternative would be making implicit capture an opt-in feature (similar to<br class="">C++):<br class=""><br class="">func foo() {<br class=""> &nbsp;&nbsp;&nbsp;let a = 5<br class=""> &nbsp;&nbsp;&nbsp;let b = "Ziggy"<br class=""> &nbsp;&nbsp;&nbsp;let c = ["Weild", "Gilly"]<br class=""><br class=""> &nbsp;&nbsp;&nbsp;let d = { [a] in<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let years = a // ok<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let artist = b // error: implicit capture in not allowed for 'd'<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let others = c // error: implicit capture in not allowed for 'd'<br class=""> &nbsp;&nbsp;&nbsp;}<br class=""><br class=""> &nbsp;&nbsp;&nbsp;let e: @capture_all () -&gt; () = { [a] in<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let years = a // ok<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let artist = b // ok<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let others = c // error: implicit capture in not allowed for 'e'<br class=""> &nbsp;&nbsp;&nbsp;}<br class="">}<br class=""><br class="">Obviously, this version would be a breaking change.<br class=""><br class="">I have no attchment to the syntax. Chris has brought up moving @noescape<br class="">before variable types declaration, so putting @explicit_capture there seems<br class="">natural.<br class=""><br class="">Thoughts?<br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></div></blockquote></div><br class=""></body></html>