If-in with Equatable Sequence

Hello Swift Community, thanks to all of you for this nice programming language

Let's create a ∈ operator (that I liked to be called "in") :

enum CompassPoint: Equatable {
    case north
    case south
    case east
    case west
}

infix operator ∈

extension Sequence where Element: Equatable {
    public static func ∈ (left: Element, right: Self) -> Bool {
        return right.contains(left)
    }
}

let point = CompassPoint.north
let validPoints = [CompassPoint.north, .south]
// validPoints.contains(point)
if point ∈ validPoints {
    print("\(point) is valid")
} else {
    print("\(point) is not valid")
}

I can now write code like this:

if point in [CompassPoint.north, .south] {

As we have the for-in, I think the if-in could be valuable as it is highly readable way to look if an item is in an Array

Side question about negation of this test, does 'not in' looks a nice idea:

if point not in [CompassPoint.north, .south] {

or maybe just use ! before the test, the 'not in' is more readable to me

I don't know how eveyone else but most people who started their programming experience in Pascal, <> is an operator for "not equal", i.e. what is in C-based languages known as !=. Not sure if that's relevant, but to me the operator is not self-explanatory and with my background, it's even confusing...

1 Like

My intuition tells me the idea of having multi-purpose keywords is rather picky, but in terms of ergonomics, it does look more neat, especially for array literals, than contains. With in, that is, not the operator. As an option, this can be implemented as sugar for

for foo in sequence where foo == point {
  ...
  break;
}

and replaced accordingly during IRGen without further tying the compiler to the stdlib. This, however, doesn't take advantage of the performance dependent contains method.

Update operator to be ∈ (thanks to Nevin)

The idea was to have "in" instead of the operator

Without commenting on anything else, the proper spelling for the “is an element of” operator is

If we were going to add this, I think it would be an overload of the in operator. But I think this may fall under the commonly rejected list along with "and" and "or"

Unless I am mistaken, in is a keyword, not an operator (so it might not even be possible to “overload” it).

It can be both. Just like as is a keyword in the Swift language, it represents both the casting operator, as well as functioning as a pattern match casting operator. In most cases in in Swift could be called the range or iterator operator.

One of my favorite memories from my programming language classes in college was the professor asking what new was in the Java language. It took us about 5 minutes and much scolding from the professor before we came up with the answer, "operator". In Java it's the constructor operator.

Whithout commenting on anything else, I would make this more generic, like so:

infix operator ∈

extension Collection where Element: Equatable {
    public static func ∈ (left: Element, right: Self) -> Bool {
        return right.contains(left)
    }
}
1 Like

if-in could possibly make sense as a sort of generalisation of for-in. It's not a very high priority though, as the desugared form is straightforward compared to for-in, which has to make the iterator and advance it. In other words:

for item in items { … }
// versus
var itemsIterator = items.makeIterator()
while let item = itemsIterator.next() { … }

is a lot more onerous than

if item in items { … }
// versus
if items.contains(item) { … }

Sequence*

1 Like

I was just curious if someone would notice. :smile:

Of course you're right. I was just too lazy to edit it, when I noticed that myself…

Thanks for your feedback, just updated the first post, and added side question about negation of this test

Replaced Collection by Sequence in both first post and title