<div dir="ltr"><div>That&#39;s a useful pattern, but the implementation above creates a function that has both a return value and a side effect, which is likely to be unexpected for many readers. </div><div><br></div><div>public func replace&lt;T&gt;(inout a: T?, with b: T?, andCleanOldValue clean:T-&gt;()) { ... }</div><div><br></div><div>replace(&amp;prop, with: newValue) { oldValue in</div><div>    oldValue.clean()</div><div>}</div><div><br></div><div>As a bonus one can automatically unwrap nil.</div><div><br></div><div>Although in real life I tend to move this logic to property accessors, e.g.</div><div><br></div><div>// Currently executing task. This property manages task state.</div><div><br></div><div>var task: NSURLSessionTask? {  </div><div>  willSet { task?.cancel() } </div><div>  didSet { task?.resume() }</div><div>}</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 14, 2015 at 7:59 AM, Dave Abrahams via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><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><span class=""><blockquote type="cite"><div>On Dec 13, 2015, at 2:21 PM, Kevin Ballard via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br><div>




<div><div>A function I find myself defining in a lot of my projects looks like the following:<br></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">/// Replace the value of `a` with `b` and return the old value.<br></span></div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">public func replace&lt;T&gt;(inout a: T, with b: T) -&gt; T {<br></span></div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">    var value = b<br></span></div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">    swap(&amp;a, &amp;value)<br></span></div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">    return value<br></span></div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">}<br></span></div>
<div> </div>
<div>This is a pretty simple function, and useful in a wide variety of circumstances, so I&#39;d love to get it into the standard library. It doesn&#39;t actually enable any behavior that wasn&#39;t previously possible, but it does shrink some common code patterns, and I find the shorter code easier to read.<br></div>
<div> </div>
<div>An example of a place where I use it often is in replacing an optional property with a new value (or with nil) and cleaning up the previous value. Assuming a property like<br></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">var task: NSURLSessionTask?<br></span></div>
<div> </div>
<div>This replaces<br></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">if let task = self.task {<br></span></div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">    task.cancel()<br></span></div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">}<br></span></div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">task = nil<br></span></div>
<div> </div>
<div>with<br></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">replace(&amp;task, with: nil)?.cancel()<br></span></div>
<div> </div>
<div>Or sometimes I use it like<br></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">if let value = replace(&amp;prop, with: newValue) {</span><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">    // multi-line cleanup</span><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif">}</span><span style="font-family:menlo,consolas,&quot;courier new&quot;,monospace,sans-serif"><br></span></div>
<div> </div>
<div>This is particularly nice if it&#39;s a COW value that I want to mutate, as it means I don&#39;t have to worry about getting unwanted copies due to the property still holding the old value while I muck with it.<br></div></div></div></blockquote><div><br></div></span><div>This is a generalization of the postincrement pattern (mutate a value and return the original) and given that we&#39;re moving away from that I&#39;m not sure it&#39;s something we want to enshrine in the standard library. That said, here&#39;s a question: looking at your use cases, how many of them are using something other than nil (or some moral equivalent) as the second argument?  If this is effectively a non-destructive move in nearly all cases, I&#39;d rather support that more directly.</div><div><br></div><div>If cases other than &quot;nondestructive move&quot; are common <u>enough</u>, I&#39;d consider something like this syntax instead:</div><div><br></div><div>  (task &lt;- nil).cancel()</div><div><br></div><div>But I strongly suspect this isn&#39;t a common enough pattern to warrant introducing an operator.</div><span class=""><div><br></div><blockquote type="cite"><div>

<div>Question: For trivial backwards-compatible API changes like this, does a proposal PR need to be submitted to the swift-evolution repo, or is discussion on this ML sufficient before submitting a patch?</div></div></blockquote><br></span>A proposal is needed for all new/changed API.</div><div><br></div><div>-Dave</div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=1p9Jer2O6jVE9KWvo-2B9iUaEyN8slp4IizyiLwsfp54OZXZs-2Bll1DicftS07fy3Z8pki5ncqRo9ycGwxqoCngq0JZlTJ4VDpqHr1So-2BBTPULnx-2FqGqyOd5NaZDA8xyuZezEmmts05xItH8SxttnvPDnRyeHrNQPKcg1rl5K3ftbALE6bdqd9dsPlSAssYoupbWZ5hPzBl8fpweqq9hg18Rj1ipqbuVvhhkmi72exv0Gc-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>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">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>
<br></blockquote></div><br></div>