<div style="white-space:pre-wrap">Honest question, where&#39;s the guarantee that the optimizer isn&#39;t allowed to optimize defer {val} away? </div><br><div class="gmail_quote"><div dir="ltr">On Thu, Dec 31, 2015 at 00:33 Joe Groff via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Dec 30, 2015, at 1:27 PM, Kevin Ballard &lt;<a href="mailto:kevin@sb.org" target="_blank">kevin@sb.org</a>&gt; wrote:</div><br><div>




<div><div>On Wed, Dec 30, 2015, at 09:53 AM, Joe Groff wrote:<br></div>
<blockquote type="cite"><div> </div>
<div><blockquote type="cite"><div>On Dec 29, 2015, at 8:55 PM, Kevin Ballard via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br></div>
<div> </div>
<div><div><div>An alternative solution is to do what Rust and C++ do, which is to use RAII. Which is to say, instead of introducing a new language construct that&#39;s explicitly tied to a scope, you just use a struct to represent the resource that you hold (e.g. a File that represents an open file). Of course, this does require some changes to structs, notably the addition of a deinit. And if structs have a deinit, then they also need to have a way to restrict copies. This is precisely what Rust does; any struct in Rust that implements Drop (the equivalent to deinit) loses the ability to be implicitly copied (a second trait called Clone provides a .clone() method that is the normal way to copy such non-implicitly-copyable structs).<br></div>
</div>
</div>
</blockquote><div> </div>
<div>deinit doesn&#39;t make sense for value types. Classes already support deinit, and you can use withExtendedLifetime to bound the lifetime of a resource-holding class. It would be reasonable to have a scoped lifetime marker similar to ObjC ARC too.<br></div>
</div>
</blockquote><div> </div>
<div>If you run with the idea that any resource-holding class should also be the mechanism by which you access the resource (e.g. a LockGuard that represents holding the lock and also provides access to the guarded value) then there&#39;s no need for extended lifetimes, because as long as you&#39;re accessing the resource, you&#39;re keeping the resource-holding class alive. I suppose there might be rare cases where you need to extend the lifetime of a resource-holding class even when you&#39;re not accessing the resource, just to guarantee e.g. order of resource releasing, but you can always just say something like `withExtendedLifeetime(&amp;val) {}` at the end of the scope to ensure the value is still alive at that point. Although I&#39;d really like to define `_ = val` as guaranteeing that the value is alive at that point (the expression doesn&#39;t actually do anything, but because it references `val` it expresses the programmer&#39;s intent that `val` should still be alive at that point in time). Alternatively, if we end up with move-only structs (or uniquely-owned classes), we could even define the expression `_ = val` as &quot;dropping&quot; the value , i.e. forcing it to deinit at that spot (because it&#39;s moving the value out of the `val` variable). This would be analogous to Rust&#39;s `std::mem::drop()` function (which is literally defined as `pub fn drop&lt;T&gt;(_x: T) { }` because all it does is move the value into the function and then forget about it).</div></div></div></blockquote><br></div></div><div style="word-wrap:break-word"><div>Another possibility I&#39;ve thought of is defining `defer { val }` to guarantee that val remains alive until the defer fires on scope exit. That might let us leave `defer` as the one &quot;guarantee something happens exactly at scope exit&quot; language construct.</div><div><br></div><div>-Joe</div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=1p9Jer2O6jVE9KWvo-2B9iUaEyN8slp4IizyiLwsfp54ON78XUWtfWQCh3jsfywVsyak3nAoJrIjXMd46hcYISLn8I0fa1d4V4ogzdGtKmyrGn-2B1UlqS7n-2FvLwVfz4125n-2B5c89s5Hs-2FB5QoeWaZh8YNfbECV7mT-2Bwd06NG0JnSFlx-2BFP596YgwL-2FqWAEdsdeRM38cqwxWBS5soAF3k2cNTupM98BX-2FQ1O6AoGTFViGLI-3D" alt="" width="1" height="1" border="0" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important">
</div>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>