`isNotEmpty` on Array

What useful generic algorithms, spanning those different types, do you see being enabled by this new protocol?

2 Likes

I feel like almost nobody who wants sugar for

guard !myCollection.isEmpty { ā€¦ }

is going to be happy with

guard let nonEmpty = myCollection.nonEmpty else {...}

I would also say that support for non-empty collections in the standard library is a tricky issue, because any methods that might remove an item would need to drop back to the possibly-empty form, limiting the use cases to situations where you preserve or increase the count. The benefits also seem fairly minor, mostly removing some Optional wrappers and precondition tests. The cost for these benefits is the need to maintain a whole parallel implementation for most/all generic Collection methods, preserving the distinction.

In similar situations, Swift seems to prefer a more pragmatic approach (e.g. preferring to traffic in Int, even for things like counts that can't be negative), instead enforcing these kind of constraints with preconditions.

It's not so much sugar as it is clarity around the ! symbol.

I don't think it should be implemented that way. Instead it should probably be a special set of annotations (or something similar) that get carried around with the type. I don't want to derail the discussion with implementation of non-empty collections (which won't come for a while), but I think it could be done without parallel implementations (or at least any written by humans).

It is true that anything which decreases the count would need to be possibly-empty. It is also true that anything that adds to the count will be non-empty. In my experience, the percentage of code which removes things from collections is much smaller than that which adds to them. All of those little checks and wrap/unwraps do add up.

As you might surmise, I don't have any specific generic algorithm an Emptiable protocol would enable. I find it interesting for two reasons:

Clarity: I find "isInhabited" to be much clearer and easier to reason about than "isEmpty == false" & "!isEmpty" (& even "isNonEmpty").

Consistency: Across a large code base utilizing a wide variety of types that implement "isEmpty", consistently having "isInhabited" & "inhabitedValue" available is invaluable.

I find the following concise & clear compared to other spellings:

guard let inhabitedStrings = strings.filter { $0.isInhabited }.inhabitedValue
else {
    return
}

Implementing "isNonEmpty" for clarity in Collection misses the opportunity to clarify all the other types that are emptiable.

1 Like

I too like isInhabited better than isNotEmpty. I find getting rid of the negation makes things clearer than just moving the negation around.

It doesn't necessarily have to come with a protocol though.

I've never heard anyone refer to a non-empty array as an inhabited array, is that something people do? Or is it mostly an attempt to get rid of the negation? I generally agree that negations in boolean property names should be avoided because you may end up with double negatives, but that will never happen in the case of isNotEmpty because you'd just use isEmpty if you want to negate it.

2 Likes

I weakly favour the addition of isNotEmpty, somewhat more strongly that of isEven / isOdd and rather more strongly isMultiple(of:). But I'll agree that the amount of discussion for such minor changes is not proportional to the actual utility derived, especially compared with bigger topics. It's a classic case of bikeshedding. So either:

  • Strictly additive, non-breaking changes that have popular demand / precedent, get added without a lot of bureacracy; or
  • More unambiguous guidelines that can be applied to pitches are defined, and things like isNotEmpty are ruled out faster.

I can understand the reasoning behind the second option (even when coming from sugary Ruby land). At the same time, nothing is stopping anyone from creating a swift-sugar library, including isNotEmpty, isEven et al., which can be what ActiveSupport was for Ruby: a library that is well-known and can be added in order to enable nicer syntax and sugar. If there was an official package index, that would make the situation even better. In time, this library could become something that is well-maintained and used by a lot of projects.

4 Likes

As for whether itā€™s done with any regularity in software development, Iā€™m not sure. I suggest it for two reasons:

  1. Itā€™s a ā€œterm of artā€ in both classical mathematics & set theory, among others.
  2. Itā€™s not a ā€œnegationā€ and thus enhances clarity.

If ā€œisNotEmptyā€ (or whatever color the bikeshed is painted) is added merely to Array or even just Collection, then Iā€™m against this pitch. But when viewed more generally, as a protocol to which both Collection and SetAlgebra conform (something we canā€™t add retroactively), then Iā€™m for it.

1 Like

I like the idea of a secondary library containing this kind of extensions (which I believe already exists in Github). I think the main barrier for the adoption of such libraries is that they are not official, making the developers afraid of adding a third party dependency, which will be used all around the codebase and can not be isolated. What about an official extension of the standard library to contain all this syntactic sugar coming up lately?

1 Like

swift evolution: calm down no oneā€™s talking about adding .isNotEmpty to the standard library

swift evolution: what if we added .isNotEmpty to the standard library

1 Like

IMHO, there really shouldn't be this extended discussion about such trivial matters. It's just bikeshedding. Either this is added or it isn't. Neither of these two options is going to make or break Swift.

How about instead:

  • Standardise on a package management solution. Yes, there is the SPM, but is anyone actually using it? (We use it on the server side, but I mean in iOS land).
  • Building a package index
  • Building a well-maintained (maybe even (semi-)official?) "Swift sugar" library (or multiple ones), so everyone can choose for themselves how much of it they want to have
  • Let the community decide whether the Swift sugar is cool or not cool (see Ruby with ActiveSupport).
2 Likes

I think that once Xcode support for SPM becomes better then it will be possible to use it in iOS land.

I was actually thinking about this. This could satisfy a lot of people if whenever there's something deemed as useful but "too much sugar, not enough protein" for the stdlib then it could be placed in the (semi) official "Swift Sugar" library. Then people who want the sugary stuff can just import Sugar and get the little niceties they want.

The problem with this is how do we get enough wide-spread support to become (semi) official? There are already several "sugary" libraries out there. I think that in order for one to become the de facto sugar standard it's going to need support from Apple and maybe even it's own evolution process. After all, we don't want just anyone adding all the sugar they could possibly want, there have to be some limits (even to a "sugar-only" library).

I agree that over time, some of the sugar could be pulled into the stdlib if it proves useful enough and the actual usage of it is widespread enough. (ie: If practically everyone is importing Sugar for the same thing that's being used in most project, it may be a good idea to just include it in the stdlib).

1 Like