<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="">While I can kind of see where you’re coming from I’m not sure about the change; the key thing about defer is that it doesn’t just execute in the cases you explicitly define, but can also occur if exceptions are thrown and other exit cases that could be all over the scope.</div><div class=""><br class=""></div><div class="">To compare with other languages, I’ve used several that achieve this with a finally block instead, usually as part of a try/catch like so:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">try {&nbsp;doSomethingThatCanThrow(); return 1; }</font></div><div class=""><font face="Monaco" class="">catch (Exception e) { print(e);&nbsp;return 0; }</font></div><div class=""><font face="Monaco" class="">finally { doSomeCleanup(); }</font></div></blockquote><div class=""><br class=""></div><div class="">Here you have two possible exit points, and in both cases the code in the finally block is executed. But it’s pretty rigid.</div><div class=""><br class=""></div><div class="">This is fine in cases like you suggest where it makes a bit more sense visually, but the cool thing about Swift is that you can declare defer blocks all over the place, build upon them and so-on. It means you can group your cleanup code with the statements that actually require the cleanup, even if there is a ton of extra code that comes afterwards. For example, opening a TCP connection may use a defer block right away to ensure the connection is closed cleanly and any buffers are cleared regardless of how the method ends (normally, IO error etc.), but before that happens there may be a whole load of parsing and other operations before you hit the final return statement.</div><div class=""><br class=""></div><div class="">It’s also pretty clear from the keyword defer; putting it after the return statement actually makes less sense, as there is nothing for it to be deferred in relation to (as there’s nothing else left to do).</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I’d say that if you want cleanup to appear visually afterwards you’d be better off promising a finally block, this could be nice to have, especially if it could be applied to most blocks like so:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>do {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>somethingThatCouldThrow()</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>if someCondition { return }</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}&nbsp;finally {&nbsp;someCleanup() } // Executed whether the block throws, returns or completes normally</font></div><div class=""><font face="Monaco" class=""><br class=""></font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>for eachValue in theValues {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>if&nbsp;doSomethingTo(eachValue) { break }</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>if someCondition { return }</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>else { throw SomeError() }</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>} finally { doSomeCleanup() } // Executes regardless of whether the loop ends normally, breaks, returns or throws</font></div><div class=""><br class=""></div><div class="">And so-on. I’d say that defer is more flexible overall, but there could be some cause for this visually so you can move simpler deferred code away from the main method body.</div><br class=""><div><blockquote type="cite" class=""><div class="">On 6 Jun 2016, at 20:50, donny wals 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="">Hi,<br class=""><br class="">When we’re using defer we write some code that we want to execute the moment a scope exits.<br class="">This leads to code that could read like:<br class=""><br class="">let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -&gt; Int in<br class=""> &nbsp;&nbsp;&nbsp;defer { pair = (pair.1, pair.0 + pair.1) }<br class=""> &nbsp;&nbsp;&nbsp;return pair.0<br class="">}<br class=""><br class="">What I find strange about this is that we have to write the code that we want to execute after the return before the return.<br class=""><br class="">I’d like to propose a change to defer that would allow the above code to be written as:<br class=""><br class="">let fibonacci = sequence(state: (0, 1)) { (pair: inout (Int, Int)) -&gt; Int in<br class=""> &nbsp;&nbsp;&nbsp;return pair.0<br class=""> &nbsp;&nbsp;&nbsp;defer { pair = (pair.1, pair.0 + pair.1) }<br class="">}<br class=""><br class="">This would make the intent of the code more clear (return first, then mutate state). Not all cases can benefit from this change, but anytime you exit a scope using a return I think it might be more clear to define the defer after the return. The code would more closely mirror the intent of the code.<br class=""><br class="">A rule of thumb I’ve come up with for this is that whenever you’re using return to exit a scope, any defer in that same scope should be executed regardless of it’s position in that same scope. This proposal would supplement the way defer currently works.<br class=""><br class="">What do you all think?<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>