<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto">I am yet another one that tries to never use <b>!</b><div><br></div><div></div><div>It feels like bad heritage from C, and it probably should be removed from Swift in the same way <b>for(;;)</b> and <b>++</b>/<b>--</b> where removed.&nbsp;</div><div><br></div><div><b>!</b> does not provide any unique functionality, as it is redundant to “== false”. Other than syntax sugar, it does not add any value to the language.&nbsp;</div><div><br></div><div>I feel a mutating <b>toggle()</b>, <b>invert()</b> or <b>flip()</b> method on <b>Bool</b> provides much more value. The non-mutating counterpart however should probably not be included in the standard library, as it would also be redundant to “== false”.&nbsp;</div><div><br><div id="AppleMailSignature"><div style="direction: inherit;">Eneko Alonso&nbsp;</div></div><div><br>On Jan 12, 2018, at 14:34, Anders Kierulf via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><span>I also avoid using ! for negation when possible, and `toggle` or `invert` will be helpful, but in many cases I think the negative case is better expressed directly. For example, I find that using `nonEmpty` instead of !isEmpty makes the code easier to read: </span><br><span></span><br><span> &nbsp;extension String {</span><br><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var nonEmpty: Bool { return !self.isEmpty }</span><br><span> &nbsp;}</span><br><span></span><br><span> &nbsp;if !string.isEmpty { … }</span><br><span></span><br><span> &nbsp;if string.isEmpty.inverted() { … }</span><br><span></span><br><span> &nbsp;if string.nonEmpty { … }</span><br><span></span><br><span>For the case of `contains`, maybe define `lacks`?</span><br><span></span><br><span> &nbsp;if !items.contains(item) { ... }</span><br><span></span><br><span> &nbsp;if items.contains(item).inverted() { ... }</span><br><span></span><br><span> &nbsp;if items.lacks(item) { ... }</span><br><span></span><br><span>Anders Kierulf</span><br><span></span><br><blockquote type="cite"><span>On Jan 12, 2018, at 12:54 PM, Alejandro Martinez via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>I wouldn't go as far as to ask to fade out ! but in all my code I end</span><br></blockquote><blockquote type="cite"><span>up doing == false just for readability. That ! knows who to hide</span><br></blockquote><blockquote type="cite"><span>himself too well :P</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>On Fri, Jan 12, 2018 at 10:13 AM, Adrian Zubarev via swift-evolution</span><br></blockquote><blockquote type="cite"><span>&lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:</span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span>I’m not sure if this would be considered or not, but I would like if the</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>negation operator `!` would fade out.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>If this is ever going to a review then I’d suggest that we add a pair of</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>functions, one mutating and the other non-mutating.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>extension Bool {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> mutating func invert() {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;self = !self</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> func inverted() {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;return !self</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>I’d rather use `inverted` instead of `!` because of the readability this</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>function provides.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>if !items.contains(item) { ... }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>if items.contains(item).inverted() { ... }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>——</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>I personally have some other extensions like:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>extension Bool {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> @discardableResult</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> func whenTrue&lt;T&gt;(execute closure: () throws -&gt; T) rethrows -&gt; T? {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;if self { return try closure() }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;return nil</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> @discardableResult</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> func whenFalse&lt;T&gt;(execute closure: () throws -&gt; T) rethrows -&gt; T? {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;if !self { return try closure() }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;return nil</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> }</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>But this is more a personal preference.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>——</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>That said, if the community is fine with the `invert/inverted` pair then I’d</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>say go for it ;)</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Am 12. Januar 2018 um 09:14:22, Nate Cook via swift-evolution</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>(<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>) schrieb:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>On Jan 12, 2018, at 12:15 AM, Chris Eidhof via swift-evolution</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>&lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Hey SE!</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>When we have a bunch of nested structs:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;struct Sample {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var bar: Bar</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;struct Bar {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var show: Bool</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;var foo = Sample(bar: Bar(show: false))</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>It can be repetitive to toggle a deeply nested boolean:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;foo.bar.show = !foo.bar.show // duplication</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>I sometimes add a `toggle` extension on `Bool`</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;extension Bool {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mutating func toggle() {</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self = !self</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;}</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>This allows you to write the same code without duplication, and makes the</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>intent clearer:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> &nbsp;&nbsp;foo.bar.show.toggle()</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>I like it!</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>In other languages, I don't think the `toggle` would make as much sense, but</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>the mutable self makes this very useful.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>After I posted it on Twitter, it turns out I'm not the only one:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="https://twitter.com/PublicExtension/status/730434956376346624">https://twitter.com/PublicExtension/status/730434956376346624</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>I would have gone straight to a proposal, but I think we can do some</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>bikeshedding about the name of `toggle`?</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Another verb that could work is `invert`.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>The `!` operator that does this is the negation operator, but I think</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>`negate` could sound to some like "make this false" rather than toggling.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Nate</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>_______________________________________________</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>swift-evolution mailing list</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>_______________________________________________</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>swift-evolution mailing list</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>-- </span><br></blockquote><blockquote type="cite"><span>Alejandro Martinez</span><br></blockquote><blockquote type="cite"><span><a href="http://alejandromp.com">http://alejandromp.com</a></span><br></blockquote><blockquote type="cite"><span>_______________________________________________</span><br></blockquote><blockquote type="cite"><span>swift-evolution mailing list</span><br></blockquote><blockquote type="cite"><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br></blockquote><blockquote type="cite"><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></blockquote><span></span><br><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div></body></html>