<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="">Let’s try again with less of a sleepy-sick stupor. =)</div><div class=""><br class=""></div><div class="">My concern is that the name of the function is the only indicator for non-struct types when looking at the signature. For structs, we can get more assurance; e.g. the bug demonstrated below cannot happen. However, that doesn’t mean the opposite bug is avoidable: return a copying instead of mutating self.</div><div class=""><br class=""></div><div class=""><div class="">The problem I was trying to illustrate, and did a really poor job at, is that the convention doesn’t actually provide us with any guarantees that our implementations are correct. So when I say this:</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">I guess my point is this: codifying a convention seems pre-mature as&nbsp;that convention doesn't bring the safety goals of the language into a&nbsp;place that's verifiable. All of the other guidelines are simply about&nbsp;clarity of use, this convention has a far reaching impact.</blockquote></div></div><div class=""><br class=""></div><div class="">Here’s a demonstration of when the guidelines was applied incorrectly, either due to ignorance of the guidelines or simply a copy/paste type bug.</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Menlo" class="">var&nbsp;bar =&nbsp;Bar(items: [2,&nbsp;1,&nbsp;3])</font></div><div class=""><font face="Menlo" class="">let&nbsp;filteredBar =&nbsp;bar.filter&nbsp;{ $0 !=&nbsp;3&nbsp;}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">bar.items &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// output: [2, 1 3]</font></div><div class=""><font face="Menlo" class="">filteredBar.items &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// output: [2, 1]</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">let&nbsp;filteredSortedBar =&nbsp;bar</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;.filter&nbsp;{ $0 !=&nbsp;3&nbsp;}</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;.sort()</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">bar.items &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// output: [2, 1, 3]</font></div><div class=""><font face="Menlo" class="">filteredSortedBar.items &nbsp; &nbsp; &nbsp; &nbsp;// output: [1, 2]</font></div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">let&nbsp;sortedFilterBar =&nbsp;bar</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;.sort()</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;.filter&nbsp;{ $0 !=&nbsp;3&nbsp;}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">bar.items &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// output: [1, 2, 3] WHAT?</font></div><div class=""><font face="Menlo" class="">sortedFilterBar.items &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// output: [1, 2]</font></div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">var&nbsp;expected =&nbsp;Bar(items: [2,&nbsp;1,&nbsp;3])</font></div><div class=""><span style="font-family: Menlo;" class="">expected</span></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;.filterInPlace&nbsp;{ $0 !=&nbsp;3&nbsp;}</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;.sortInPlace()</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><span style="font-family: Menlo;" class="">expected.items &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // output: [1, 2]</span></div></blockquote><div class=""><br class=""></div><div class="">When reading the code with an understanding of the guidelines, this code is misleading as to what it should be doing. That’s what I find dangerous. Of course, we can argue on the merits of these types of bugs, but we’ve all seen conventions misused and it sucks.</div><div class=""><br class=""></div><div class="">If this convention is just a stop-gap until a language feature can be built to help with this, then ok.&nbsp;</div><div class=""><br class=""></div><div class="">-David</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">sample implementation that demonstrates the bug that gets us out-of-sync with the guidelines:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Menlo" class="">public&nbsp;class&nbsp;Bar&lt;T : Comparable&gt; {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;var&nbsp;items: [T]</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;init(items: [T]) {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;self.items&nbsp;= items</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;func&nbsp;sortInPlace() -&gt;&nbsp;Self&nbsp;{</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;self.items.sortInPlace&nbsp;{ $0&nbsp;&lt;&nbsp;$1 }</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;self</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;func&nbsp;sort() -&gt;&nbsp;Self&nbsp;{</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; self.items.sortInPlace&nbsp;{ $0&nbsp;&lt;&nbsp;$1 }</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;self</font></div><div class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo;" class="">}</span></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;func&nbsp;filterInPlace(includeElement: (T) -&gt;&nbsp;Bool) -&gt;&nbsp;Self&nbsp;{</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;self.items&nbsp;=&nbsp;self.items.filter(includeElement)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;self</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;func&nbsp;filter(includeElement: (T) -&gt;&nbsp;Bool) -&gt;&nbsp;Bar&lt;T&gt; {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;let&nbsp;newItems: [T] =&nbsp;self.items.filter(includeElement)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;Bar(items: newItems)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div><div class=""><font face="Menlo" class="">}</font></div></blockquote><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 24, 2016, at 7:18 PM, Dave Abrahams &lt;<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><br class="">on Sun Jan 24 2016, David Owens II &lt;<a href="http://david-at-owensd.io" class="">david-AT-owensd.io</a>&gt; wrote:<br class=""><br class=""><blockquote type="cite" class="">Sorry, I meant to add the do() version too in order to show the<br class="">difference better. /sigh<br class=""></blockquote><br class="">do() version?<br class=""><br class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">On Jan 24, 2016, at 4:53 PM, David Owens II via swift-evolution<br class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">I guess my point is this: codifying a convention seems pre-mature as<br class="">that convention doesn't bring the safety goals of the language into a<br class="">place that's verifiable. All of the other guidelines are simply about<br class="">clarity of use, this convention has a far reaching impact.<br class=""></blockquote><br class="">Sorry, could you clarify what you mean by "bring the safety goals of the<br class="">language into a place that's verifiable" and clarify why having a "far<br class="">reaching impact" would somehow conflict with being "about clarity of use?"<br class=""><br class="">It seems to me that this convention is about how to express whether a<br class="">method is going to mutate so it's clear at the use-site. &nbsp;What am I<br class="">missing?<br class=""></blockquote><br class=""><br class="">The problem is it's unclear to me whether you mean mutate in the<br class="">true sense of the word or only applied to a struct with a function<br class="">annotated with the mutating keyword.<br class=""><br class="">The naming convention provides no safety when dealing with<br class="">non-struct types as we cannot enforce that a method on a class does<br class="">not mutate it's internal members.<br class=""><br class="">That's the clarity I'm looking for.<br class=""><br class="">Given this API set:<br class=""><br class="">protocol InPlaceable {<br class=""> &nbsp;&nbsp;&nbsp;mutating func doInPlace()<br class="">}<br class=""><br class="">public struct Foo: InPlaceable {<br class=""> &nbsp;&nbsp;&nbsp;mutating func doInPlace() {}<br class="">}<br class=""><br class="">public class Bar: InPlaceable {<br class=""> &nbsp;&nbsp;&nbsp;func doInPlace() {}<br class="">}<br class=""><br class="">var lie: InPlaceable = Bar()<br class="">lie.doInPlace()<br class=""><br class="">let lie2 = Bar()<br class="">lie2.doInPlace()<br class=""><br class="">The convention will tell us a lie unless we are extremely<br class="">careful. It's this lie that concerns me. We cannot guarantee that<br class="">the "doInPlace" truly matches the definition we are seeking.<br class=""><br class=""><br class="">-David<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=""></blockquote><br class=""></blockquote><br class="">-- <br class="">-Dave<br class=""></div></div></blockquote></div><br class=""></body></html>