isNonEmpty


(Svein Halvor Halvorsen) #11

I'm not sure I'm advocating it, because I haven't given it much thought yet. But, if you want to solve the problem of the negation being visually far separated from the relevant expression, you could add some kind of extension on Bool:

extension Bool {
  var not: Bool { return !self } 
}

if viewModel.nested.collection.isEmpty.not { /* ... */ }
if model.names.contains(element).not { /* ... */ }
// ... etc

(Jens Jakob Jensen) #12

That does improves locality. But it doesn't read like English to me, sorry :slight_smile:


(Svein Halvor Halvorsen) #13

Sure, I agree. Maybe you can think of some better name?
Because if you do, you have solved it for every bool property and function returning a bool.


(Jens Jakob Jensen) #14

That's kind of true. But even if I change it to ask whether collection.isEmpty.isFalse, or whether collection.isEmpty.negated, or whatever, it's still sort of a double negative and imposes additional cognitive load if I just want to know whether the collection is non-empty.


(Max Howell) #15

But does a non-empty range have elements? Perhaps it does.

While you are right that we don’t think of them as elements for Range, the documentation does refer to them as such: https://developer.apple.com/documentation/swift/range (even if this is because it is lifted from the protocol, which I suspect is the case).

And the associatedtype of the underlying protocol is Element.

But a non-empty geometry does not, I think.

I'm sure it won't fit as well with some potential Sequence conformances, but is there one in particular you mean?


(Justin Jia) #16

Core team:

You can also use isEmpty == false.


(Rudolf Adamkovič) #17

Speaking of extending Bool, we could add Bool.toggled as a non-mutating variant the recently added Bool.toggle().


(Jens Jakob Jensen) #18

Envelope.isEmpty / Envelope.isNonEmpty. Not a Sequence, but we still need to ensure it's non-empty before using it.

if collection.isEmpty.toggled { is still much worse than if collection.isNonEmpty {. But better than if !collection.isEmpty { I guess... :slight_smile:


(Dan Turner) #19

+1 for isNotEmpty, it seems to read clear in code


(^) #20

if we add isNonEmpty to the standard library what will we use as our strawman example of a property that should not be added to the standard library?


(Jens Jakob Jensen) #21

The thing is that !isEmpty is used a lot in common code, and apparently in many cases more than isEmpty is. On top of that it really helps readability. Together it really helps readability for a lot of Swift code...

It would be great with some corpus of Swift code that could be used to make statistics for arguing these sort of things :+1:


(Xiaodi Wu) #22

Of course it's used commonly and together; that's exactly what's expected of standard library facilities: that they are used commonly in combination with each other.

The core team has made it clear that isNotEmpty is not to be included in the standard library--in fact, it is the example of what will not be included. Likewise, alternatives to ! for negation are a commonly rejected change. I really don't see what's being accomplished here by discussing further.


(Jens Jakob Jensen) #23

I guess I'm arguing two things:

  1. Perhaps it is isNonEmpty that should be in the standard library, and not isEmpty. Because of the way Swift is put together, e.g. with guard.
  2. Perhaps it would make sense to use statistics to argue the likes of isEmpty / isNonEmpty instead of treating all boolean properties the same.

(Tino) #24

I think that I use isEmpty more often in the negated form — but !isNonEmpty would feel a little bit weird.
Isn't there an established word for a populated collection in the English language? :-)


#25
extension Collection {
    public var containsAtLeastOneElement: Bool {
        return !isEmpty
    }
}

Would be a huge gain for the stdLib. :laughing:


(Jhonny Bill) #26

As I read this, I immediately thought on a @Ben_Cohen comment in one thread [coincidentally on an isNotEmpty discussion]. As Ben stated:

I think there's a real risk with the current pitches that we end up with a standard library populated with huge quantities of sugar and not enough protein.

Here's his full comment:


(Jens Jakob Jensen) #27

I did see that one, and I agree that Swift should not have both cases of all boolean properties. If that was needed, then it was an indicator of an underlying issue in Swift.

But I do think that the check for non-emptiness is special, and I don't think any perceived lack of protein should mean holding back on the sugar :wink:

BTW, I'm not advocating isNotEmpty, as the negative of isEmpty. I'm advocating isNonEmpty as a check for something being non-empty and hence useful for further processing. A key concept in Swift IMO. But perhaps this would be better solved by Collection.nonEmpty:

guard let array = array.nonEmpty {

(Josh Caswell) #28

hasElements, as Max Howell suggested above probably fits that bill best. (And happens to be the name I chose for this property personally, as I think it reads much better than the negative isNotEmpty in a guard's condition.)


(Jens Jakob Jensen) #29

While hasElements is nice for collections, it doesn't fit e.g. Envelope very well :slight_smile:


(RuiCarneiro) #30

Why not make it a language feature?

Automatically synthesise for boolean properties:

If the property has prefix is, has or will, automatically synthesise the corresponding isNot, hasNot, willNot.

For the other properties automatically synthesise the corresponding not. :slight_smile:

This might look like a bit of a funny thing, but in Swift we have "!" meaning two things: forcing (as in as!, try!, etc.), and negating (as in !myBool)

I would rather have only one meaning.