<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div><blockquote type="cite" class=""><div class="">On Mar 26, 2016, at 3:47 PM, Maury Markowitz via swift-users <<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">Before I stick my head into the other list, consider:<br class=""><br class=""> if statusCode >= 200 && statusCode <= 299<br class=""><br class="">I'm sure examples of something like this occur throughout your code. But the actual semantics of the test is hidden here, you're really testing if statusCode lies within a range. Swift 2.0 has a couple of options for this, but I find them all rather odd. The most recommended is:<br class=""><br class=""> if case 0...100 = someInteger<br class=""></div></blockquote><div><br class=""></div><div>While I prefer: </div><div><span style="font-family: Menlo;" class=""><br class=""></span></div><div><span style="font-family: Menlo;" class="">if 200...299 ~= statusCode { print("within 200-299") }</span></div><div><div class=""><font face="Menlo" class=""></font></div></div></div></div><div class=""><br class=""></div><div class="">I see that you're asking specifically about case/=. But keep that example in mind because I'm</div><div class="">going to circle back to it.</div><div class=""><div class=""><br class=""></div><blockquote type="cite" class="">This syntax has problems. For one thing, it's written backwards compared to most people's code...<br class=""><br class=""> if someinteger == 100<br class=""><br class="">not...<br class=""><br class=""> if 100 == someinteger<br class=""><br class="">so it just *feels* wrong. In addition, the use of "case" seems odd too. And finally, there's the use of the single equals sign in a test, which goes against everything we've learned in C-like languages.<br class=""><br class="">So unless I'm missing something, can anyone offer a reason this wouldn't work?<br class=""><br class=""> if someinteger in 0...100</blockquote><br class=""></div><div class="">This is a built-in problem with "if case/=". Starting with the core statement :</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">if case pattern = value {...}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class="">It's far easier to read and understand the equivalent switch than the one-liner:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">switch (value) {</font></div><div class=""><font face="Menlo" class="">case pattern: ...</font></div><div class=""><font face="Menlo" class="">default: break</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><br class=""></div><div class="">Once you convert to a switch, the "If this value can be matched to this pattern" </div><div class="">becomes a lot less mentally weird but there's also a lot of extra fluff that if case</div><div class="">attempts to trim away. Here's a concrete example. "In the case that the pattern </div><div class="">Test.A(Int) can be matched to this value then bind x to the associated Int value"</div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""><div class="">let value = Test.A(23)</div><div class=""><br class=""></div><div class="">if case Test.A(let x) = value {</div><div class=""> print(x) // will print 23</div><div class="">}</div></font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class="">Again the switch is a lot more intuitive to read, but contains a lot of unneeded</div><div class="">details that can and should be trimmable:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Menlo" class="">switch (value) {</font></div><div class=""><font face="Menlo" class="">case Test.A(let x): ...</font></div><div class=""><font face="Menlo" class="">default: break</font></div><div class=""><font face="Menlo" class="">}</font></div></div><div class=""><br class=""></div><div class="">And here's the oddest example of this Case/= construct I can think of in terms</div><div class="">of the "read through" not matching the actual programming intent of "In the </div><div class="">case that the array indices can be matched to this value" </div><div class=""><br class=""></div><div class=""><span style="font-family: Menlo;" class="">if case array.indices = array.startIndex { print("strange but yup") }</span></div><div class=""><br class=""></div><div class="">And its switch equivalent, which is way more obvious in terms of intent:</div><div class=""><br class=""></div><div class=""><div class=""><div class=""><font face="Menlo" class="">switch (</font><span style="font-family: Menlo;" class="">array.startIndex</span><font face="Menlo" class="">) {</font></div><div class=""><font face="Menlo" class="">case array.indices: ...</font></div><div class=""><font face="Menlo" class="">default: break</font></div><div class=""><font face="Menlo" class="">}</font></div></div></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class="">Now back to your original point. Could this be expressed better? For sure. I think these are far more readable:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">if value in range {...} // vs if range ~=</font></div><div class=""><span style="font-family: Menlo;" class="">if value matches pattern {...} // vs if case pattern = value</span></div><div class=""><br class=""></div><div class="">And for these specific examples, they'd look like this in an updated Swift that adopted these changes:</div><div class=""><br class=""></div><div class=""><span style="font-family: Menlo;" class="">if statusCode in 200...299 { print("within 200-299") }</span></div><div class=""><font face="Menlo" class=""><div class="">if value matches Test.A(let x) { print(x) } // will print 23</div><div class="">if array.startIndex in array.indices { print("the ~= variation") }</div><div class="">if array.startIndex matches array.indices { print ("better example Case/=") }</div><div class=""><br class=""></div></font></div><div class="">That said, I've also made my opinion clear over there that the use of "let" and "var"</div><div class="">in "if let" unnecessarily overloads constant and variable binding (it's testing something </div><div class="">that actually acts differently than the standalone let due to unwrapping). This got nowhere</div><div class="">for a variety of compelling and less compelling reasons. (I'd prefer "if bind" even if it </div><div class="">sacrifices a variable variant.)</div><div class=""><br class=""></div><div class=""><div class="">I certainly think it's worth doing at least a [Pitch] over in -evolution with the alternate </div></div><div class="">constructs.</div><div class=""><br class=""></div><div class="">-- E</div></body></html>