<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div><div><div><div><div>FWIW, in the code I've written over the past few days in a new project, I've already used my local&nbsp;<span style="font-family: Menlo; font-size: 11px;">replace(</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">_</span><span style="font-family: Menlo; font-size: 11px;">:with:)</span>&nbsp;6 times, and I just tried to use it a 7th from within the unit tests and got an error because the function is private &gt;_&lt;<br></div>
<div>&nbsp;</div>
<div>It does turn out that nearly all of my particular uses for this function end up replacing the value with `<span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">nil</span>`, but there certainly are cases where you'd want to replace a value with some other non-<span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">nil</span>&nbsp;value (such as the example I listed in the proposal about a spot where it might be used in the stdlib).<br></div>
<div>&nbsp;</div>
<div>On Mon, Jan 11, 2016, at 01:22 PM, Jordan Rose wrote:<br></div>
<blockquote type="cite">-1 from me as well, for the same reason as Dave. In the Dictionary case, doing a lookup and then a replacement isn't just more verbose; it's actually less efficient. And I&nbsp;<i>still</i>&nbsp;wouldn't embed an updateValue(_:forKey:) in a larger expression, for clarity's sake.<br></blockquote><div>&nbsp;</div>
<div>I'm not recommending that&nbsp;<span style="font-family: Menlo; font-size: 11px;">replace(</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">_</span><span style="font-family: Menlo; font-size: 11px;">:with:)</span>&nbsp;be used as a replacement for&nbsp;<span style="font-family: Menlo; font-size: 11px;">Dictionary.updateValue(</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">_</span><span style="font-family: Menlo; font-size: 11px;">:forKey:)</span>. I just found it interesting that it has the exact same semantics (but, as you said, it's less performant).<br></div>
<div>&nbsp;</div>
<blockquote type="cite">Now, admittedly, if the assigned-to value were some complicated expression (e.g. "view.frame.size.height"), the same performance argument applies. But I still think I'd rather people just use a temporary variable.<br></blockquote><div>&nbsp;</div>
<div>What do you mean? Using `<span style="font-family: Menlo; font-size: 11px;">replace(&amp;view.frame.size.height, with: newHeight)</span>` is no less performant than doing things manually. The&nbsp;<span style="font-family: Menlo; font-size: 11px;">Dictionary.updateValue(</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">_</span><span style="font-family: Menlo; font-size: 11px;">:forKey:)</span>&nbsp;case only differs because accessing the subscript getter + setter has to look up the key twice, but `<span style="font-family: Menlo; font-size: 11px;">&amp;view.frame.size.height</span>` doesn't have to look up anything, it just has to read the property and then set it again, which is exactly what you have to do if you want to read the old value and assign a new one regardless of whether you're using a function like&nbsp;<span style="font-family: Menlo; font-size: 11px;">replace(</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">_</span><span style="font-family: Menlo; font-size: 11px;">:with:)</span>&nbsp;to do it.<br></div>
<div>&nbsp;</div>
<blockquote type="cite"><blockquote style="margin-top: 0px; margin-bottom: 0px; margin-left: 40px; padding-right: 0px; padding-left: 0px; border-style: none;"><div>self.task?.cancel()<br></div>
<div>self.task = nil<br></div>
<div>&nbsp;</div>
<div>let oldValue = self.prop<br></div>
<div>self.prop = newValue<br></div>
<div>if let oldValue = oldValue {<br></div>
<div>&nbsp; // multi-line cleanup<br></div>
<div>}<br></div>
</blockquote><div>&nbsp;</div>
<div>I'll admit the latter is not as nice, but it's definitely easier for me to read.<br></div>
</blockquote><div>&nbsp;</div>
<div>Maybe for you. I find it much easier to read<br></div>
<div>&nbsp;</div>
<div><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span style="color: rgb(187, 44, 162);">if</span>&nbsp;<span style="color: rgb(187, 44, 162);">let</span>&nbsp;oldValue = replace(&amp;<span style="color: rgb(187, 44, 162);">self</span>.prop, with:&nbsp;<span style="color: rgb(187, 44, 162);">nil</span>) {<br></p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span style="color: rgb(0, 0, 0);">&nbsp; &nbsp;&nbsp;</span>// ...<br></p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">}<br></p></div>
<div>&nbsp;</div>
<div>I recognize that many people will prefer the "manual" version, but I'm sure many people will be like me and prefer the&nbsp;<span style="font-family: Menlo; font-size: 11px;">replace(</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">_</span><span style="font-family: Menlo; font-size: 11px;">:with:)</span>&nbsp;version. I don't find the argument "I think it's easier to read &lt;some other way&gt;" to be very compelling when it comes to stdlib or language features, because we already have plenty of precedent for being able to write the same thing in multiple ways. There's also a middle ground here, if you just don't like embedding&nbsp;<span style="font-family: Menlo; font-size: 11px;">replace(</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">_</span><span style="font-family: Menlo; font-size: 11px;">:with:)</span>&nbsp;in a larger construct, that still uses a temporary variable but allows you to avoid duplicating complicated accessor expressions, e.g.<br></div>
<div>&nbsp;</div>
<div><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span style="color: rgb(187, 44, 162);">let</span>&nbsp;oldValue = replace(&amp;<span style="color: rgb(187, 44, 162);">self</span>.sections[indexPath.section].rows[indexPath.row].data, with: newValue)</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span style="color: rgb(187, 44, 162);">if</span>&nbsp;<span style="color: rgb(187, 44, 162);">let</span>&nbsp;oldValue = oldValue {</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span style="color: rgb(0, 0, 0);">&nbsp; &nbsp;&nbsp;</span>// ...</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">}</p></div>
<div>&nbsp;</div>
<div>I've also found a lot of use for&nbsp;<span style="font-family: Menlo; font-size: 11px;">replace(</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">_</span><span style="font-family: Menlo; font-size: 11px;">:with:)</span>&nbsp;in `<span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">guard</span><span style="font-family: Menlo; font-size: 11px; color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">let</span>` expressions. There especially the "manual" version sucks because it leaves a second variable lying around that you don't want anymore. In the library I'm working on right now, I have a bunch of uses of&nbsp;<span style="font-family: Menlo; font-size: 11px;">replace(</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">_</span><span style="font-family: Menlo; font-size: 11px;">:with:)</span>&nbsp;that look like<br></div>
<div>&nbsp;</div>
<div><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span style="color: rgb(187, 44, 162);">guard</span>&nbsp;<span style="color: rgb(187, 44, 162);">var</span>&nbsp;request = replace(&amp;<span style="color: rgb(187, 44, 162);">self</span>.request, with;&nbsp;<span style="color: rgb(187, 44, 162);">nil</span>)&nbsp;<span style="color: rgb(187, 44, 162);">else</span>&nbsp;{</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">&nbsp; &nbsp;&nbsp;writeResponse(Response(status: .InternalServerError, text:&nbsp;<span style="color: rgb(209, 47, 27);">"Internal server error: couldn't find active request"</span>))</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);"><span style="color: rgb(0, 0, 0);">&nbsp; &nbsp;&nbsp;</span>return</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">}</p></div>
<div>&nbsp;</div>
<div>(yes, this is actually for an HTTP server written in Swift, which I'm using to test networking code)<br></div>
<div>&nbsp;</div>
<div>What's your opinion on the alternative&nbsp;<span style="font-family: Menlo; font-size: 11px;">&lt;-</span>&nbsp;operator (which IIRC Dave suggested)? I much prefer&nbsp;<span style="font-family: Menlo; font-size: 11px;">replace(</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">_</span><span style="font-family: Menlo; font-size: 11px;">:with:)</span>, and I don't think it conflicts with stdlib conventions (it's no different than a mutating method that returns a value, it just happens to be a function, but there's not much of a difference between mutating methods and functions that take an inout first parameter), but I'd rather have this functionality as an&nbsp;<span style="font-family: Menlo; font-size: 11px;">&lt;-</span>&nbsp;operator than not have it at all. As an example, the previous two code samples, when written with&nbsp;<span style="font-family: Menlo; font-size: 11px;">&lt;-</span>, would look like<br></div>
<div>&nbsp;</div>
<div><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span style="color: rgb(187, 44, 162);">let</span>&nbsp;oldValue = (<span style="color: rgb(187, 44, 162);">self</span>.sections[indexPath.section].rows[indexPath.row].data &lt;- newValue)</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span style="color: rgb(187, 44, 162);">if</span>&nbsp;<span style="color: rgb(187, 44, 162);">let</span>&nbsp;oldValue = oldValue {</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span style="color: rgb(0, 0, 0);">&nbsp; &nbsp;&nbsp;</span>// ...</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">}<br></p><div>&nbsp;</div>
<div>and<br></div>
<div>&nbsp;</div>
<div><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span style="color: rgb(187, 44, 162);">guard</span>&nbsp;<span style="color: rgb(187, 44, 162);">var</span>&nbsp;request = (<span style="color: rgb(187, 44, 162);">self</span>.request &lt;-&nbsp;<span style="color: rgb(187, 44, 162);">nil</span>)&nbsp;<span style="color: rgb(187, 44, 162);">else</span>&nbsp;{</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">&nbsp; &nbsp;&nbsp;writeResponse(Response(status: .InternalServerError, text:&nbsp;<span style="color: rgb(209, 47, 27);">"Internal server error: couldn't find active request"</span>))</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);"><span style="color: rgb(0, 0, 0);">&nbsp; &nbsp;&nbsp;</span>return</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">}</p></div>
</div>
<div>&nbsp;</div>
<div>-Kevin Ballard<br></div>
<div>&nbsp;</div>
<blockquote type="cite"><div>Jordan<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><blockquote type="cite"><div>On Jan 9, 2016, at 16:48, Kevin Ballard via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div>
<div>&nbsp;</div>
<div><div><div>Proposal PR submitted as&nbsp;<a href="https://github.com/apple/swift-evolution/pull/93">https://github.com/apple/swift-evolution/pull/93</a><br></div>
<div>&nbsp;</div>
<div>-Kevin Ballard<br></div>
<div>&nbsp;</div>
<div>On Sun, Dec 13, 2015, at 02:21 PM, Kevin Ballard wrote:<br></div>
<blockquote type="cite"><div>A function I find myself defining in a lot of my projects looks like the following:<br></div>
<div>&nbsp;</div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">/// Replace the value of `a` with `b` and return the old value.</span><br></div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">public func replace&lt;T&gt;(inout a: T, with b: T) -&gt; T {</span><br></div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">&nbsp;&nbsp;&nbsp; var value = b</span><br></div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">&nbsp;&nbsp;&nbsp; swap(&amp;a, &amp;value)</span><br></div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">&nbsp;&nbsp;&nbsp; return value</span><br></div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">}</span><br></div>
<div>&nbsp;</div>
<div>This is a pretty simple function, and useful in a wide variety of circumstances, so I'd love to get it into the standard library. It doesn't actually enable any behavior that wasn't previously possible, but it does shrink some common code patterns, and I find the shorter code easier to read.<br></div>
<div>&nbsp;</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>&nbsp;</div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">var task: NSURLSessionTask?</span><br></div>
<div>&nbsp;</div>
<div>This replaces<br></div>
<div>&nbsp;</div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">if let task = self.task {</span><br></div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">&nbsp; &nbsp; task.cancel()</span><br></div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">}</span><br></div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">task = nil</span><br></div>
<div>&nbsp;</div>
<div>with<br></div>
<div>&nbsp;</div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">replace(&amp;task, with: nil)?.cancel()</span><br></div>
<div>&nbsp;</div>
<div>Or sometimes I use it like<br></div>
<div>&nbsp;</div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">if let value = replace(&amp;prop, with: newValue) {</span><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;"></span><br></div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">&nbsp; &nbsp; // multi-line cleanup</span><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;"></span><br></div>
<div><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;">}</span><span class="font" style="font-family: menlo, consolas, 'courier new', monospace, sans-serif;"></span><br></div>
<div>&nbsp;</div>
<div>This is particularly nice if it's a COW value that I want to mutate, as it means I don'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>&nbsp;</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?<br></div>
<div>&nbsp;</div>
<div>-Kevin Ballard<br></div>
</blockquote><div>&nbsp;</div>
<div><img border="0" height="1" width="1" alt="" src="https://www.fastmailusercontent.com/proxy/60532b88dbf4e79fa6783491c246c0338f2a36485fc3b592cf5c873deb5df76d/8647470737a3f2f25723030323431303e23647e23756e64676279646e2e65647f27766f2f60756e6f35707e6d3a554a743178495e6858605273326240557d2236487054347e433846675b4c4d2236447a40717b6150376b6f4653514367694476465742314966407151694e695a714d2232455364654672596d43723972667664516e61626035537a4744663d2232497d65774974415d22324a787e664e68447756494943517a48414b65497c455747757568373a7b64724452666a4b496767614443765a7271593337743c6345394f6864655a7b444452305564336168403f416b40307849787452337746776d6d63696831613f6d223647307763744332343855577f6f683763673d4356545a7f47353d2236437441684570555e6e6935524d2236474f4036495d23344/open" style="height: 1px !important; width: 1px !important; border-width: 0px !important;"><br></div>
</div>
<div>_______________________________________________<br></div>
<div>swift-evolution mailing list<br></div>
<div><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br></div>
<div>https://lists.swift.org/mailman/listinfo/swift-evolution<br></div>
</div>
</blockquote></div>
</blockquote></div>
</div>
</div>
</div>
</body>
</html>