> On Mar 26, 2016, at 3:47 PM, Maury Markowitz via swift-users 
> <[email protected]> wrote:
> 
> Before I stick my head into the other list, consider:
> 
>   if statusCode >= 200 && statusCode <= 299
> 
> 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:
> 
>   if case 0...100 = someInteger

While I prefer: 

if 200...299 ~= statusCode { print("within 200-299") }

I see that you're asking specifically about case/=. But keep that example in 
mind because I'm
going to circle back to it.

> This syntax has problems. For one thing, it's written backwards compared to 
> most people's code...
> 
>   if someinteger == 100
> 
> not...
> 
>   if 100 == someinteger
> 
> 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.
> 
> So unless I'm missing something, can anyone offer a reason this wouldn't work?
> 
>  if someinteger in 0...100

This is a built-in problem with "if case/=". Starting with the core statement :

if case pattern = value {...}

It's far easier to read and understand the equivalent switch than the one-liner:

switch (value) {
case pattern: ...
default: break
}

Once you convert to a switch, the "If this value can be matched to this 
pattern" 
becomes a lot less mentally weird but there's also a lot of extra fluff that if 
case
attempts to trim away. Here's a concrete example.  "In the case that the 
pattern 
Test.A(Int) can be matched to this value then bind x to the associated Int 
value"

let value = Test.A(23)

if case Test.A(let x) = value {
    print(x) // will print 23
}

Again the switch is a lot more intuitive to read, but contains a lot of unneeded
details that can and should be trimmable:

switch (value) {
case Test.A(let x): ...
default: break
}

And here's the oddest example of this Case/= construct I can think of in terms
of the "read through" not matching the actual programming intent of "In the 
case that the array indices can be matched to this value" 

if case array.indices = array.startIndex { print("strange but yup") }

And its switch equivalent, which is way more obvious in terms of intent:

switch (array.startIndex) {
case array.indices: ...
default: break
}

Now back to your original point. Could this be expressed better? For sure. I 
think these are far more readable:

if value in range {...} // vs if range ~=
if value matches pattern {...} // vs if case pattern = value

And for these specific examples, they'd look like this in an updated Swift that 
adopted these changes:

if statusCode in 200...299 { print("within 200-299") }
if value matches Test.A(let x) { print(x) } // will print 23
if array.startIndex in array.indices { print("the ~= variation") }
if array.startIndex matches array.indices { print ("better example Case/=") }

That said, I've also made my opinion clear over there that the use of "let" and 
"var"
in "if let" unnecessarily overloads constant and variable binding (it's testing 
something 
that actually acts differently than the standalone let due to unwrapping). This 
got nowhere
for a variety of compelling and less compelling reasons. (I'd prefer "if bind" 
even if it  
sacrifices a variable variant.)

I certainly think it's worth doing at least a [Pitch] over in -evolution with 
the alternate 
constructs.

-- E
_______________________________________________
swift-users mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to