I wrote these a while ago and considered proposing that they be added.
Might as well throw them into this thread since they are another approach
to solving the problem.
import Foundation
// MARK: <
public func <<T : Comparable>(lhs: T, rhs: T) -> (result: Bool,
value:T) {
return (lhs < rhs, rhs)
}
public func <<T : Comparable>(lhs: (result: Bool, value: T), rhs: T) ->
Bool {
return lhs.result && (lhs.value < rhs)
}
public func <<T : Comparable>(lhs: (Bool, T), rhs: T) -> (Bool, T) {
return (lhs < rhs, rhs)
}
// MARK: >
public func ><T : Comparable>(lhs: T, rhs: T) -> (result: Bool, value:T) {
return (lhs > rhs, rhs)
}
public func ><T : Comparable>(lhs: (result: Bool, value: T), rhs: T) ->
Bool {
return lhs.result && (lhs.value > rhs)
}
public func ><T : Comparable>(lhs: (Bool, T), rhs: T) -> (Bool, T) {
return (lhs > rhs, rhs)
}
// MARK: >=
public func >=<T : Comparable>(lhs: T, rhs: T) -> (result: Bool, value:T) {
return (lhs >= rhs, rhs)
}
public func >=<T : Comparable>(lhs: (result: Bool, value: T), rhs: T) ->
Bool {
return lhs.result && (lhs.value >= rhs)
}
public func >=<T : Comparable>(lhs: (Bool, T), rhs: T) -> (Bool, T) {
return (lhs >= rhs, rhs)
}
// MARK: <=
public func <=<T : Comparable>(lhs: T, rhs: T) -> (result: Bool, value:T) {
return (lhs <= rhs, rhs)
}
public func <=<T : Comparable>(lhs: (result: Bool, value: T), rhs: T) ->
Bool {
return lhs.result && (lhs.value <= rhs)
}
public func <=<T : Comparable>(lhs: (Bool, T), rhs: T) -> (Bool, T) {
return (lhs <= rhs, rhs)
}
// MARK: ==
public func ==<T : Comparable>(lhs: T, rhs: T) -> (result: Bool, value:T) {
return (lhs == rhs, rhs)
}
public func ==<T : Comparable>(lhs: (result: Bool, value: T), rhs: T) ->
Bool {
return lhs.result && (lhs.value == rhs)
}
public func ==<T : Comparable>(lhs: (Bool, T), rhs: T) -> (Bool, T) {
return (lhs == rhs, rhs)
}
let value = 5
if (0 < value) < 10 {
print("in the middle!")
} else {
print("nope")
}
I'd love to see `if value matches pattern`. Every time I use `if case` I
have to stop and think to remember the weird syntax. I get where it came
from, but I think `matches` better describes what happens here (one is
immediately reminded of pattern matching).
I don't know wether this might be unfeasible to do due to compiler
performance limitations, but I would support a proposal to replace `if
case` with `if value matches pattern`.
An alternative may be to introduce a custom operator that just calls `~=`
with the arguments reversed, but imho this should rather be fixed at the
language level.
– Lukas
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
···
On Sun, Mar 27, 2016 at 5:19 AM, Lukas Stabe via swift-evolution < swift-evolution@swift.org> wrote:
On 26 Mar 2016, at 18:13, Erica Sadun via swift-users < swift-users@swift.org> wrote:
On Mar 26, 2016, at 3:47 PM, Maury Markowitz via swift-users < swift-users@swift.org> wrote:
constructs.
-- E
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution