Using ! with infix functions that return Boolean

Just an idea,

If I write an infix function that returns a boolean, such as

fun String.matches(pattern: String): Boolean { ... }

I thought it would be really natural when I want to check the inverse if I could use !, like

val doesNotMatch = "..." !matches "..."

Similar to = vs !=. But sadly, this is impossible. Kotlin forces you to do it outside like, !("..." matches "...")

Anyone agree with me that "..." !matches "..." would be nice?

6 Likes

I don’t think that this could easily be achieved. The Kotlin standard libraray simply uses not as a prefix, so in your case it would be "..." notMatches "...". Not that bad, I think. It is just two additional keystrokes which hardly affect the life-time of your keyboard :wink: And it is very readable.

If I had designed Kotlin, I would have used and instead of && for logical expressions and I think words, especially if they are short, are good in code (there is a reason why the written word is important in almost all cultures).

1 Like

Sure I agree notMatches reads very nicely, but that requires writing a second function called notMatches, so then you need to write twice as many functions if you’re making a library full of these infix functions that return boolean.

1 Like

An interesting idea!

Of course it would apply only to predicates (functions returning a Boolean).

I’m not sure whether it would work well for the usual function-call syntax:

a.!predicate(b)

But it would seem very natural and logical for infix functions*. The meaning should be obvious to anyone who knows Kotlin (or has used a != operator), and the implementation would simply call the predicate and then invert the result:

a !predicate b

would be syntactic sugar for:

!(a predicate b)

From an æsthetic point of view, it would make the language more regular, as the !is and !in operators would no longer be special cases but work the same way as all other predicates. And by moving the ! nearer the predicate, it would make code easier to read, closer to English, and reduce the need for complex expressions in parens — and for notXxx duplicates of functions.

And I think it would be completely backward-compatible, too, so it wouldn’t break any existing code.

(I’ve seen many suggestions for language changes, and most of them provide less benefit than would justify the extra complexity or breaking changes — certainly not enough to overcome the initial minus 100 points. But this one really appeals to me.)


(* I haven’t seen an official reason for restricting infix usage to functions explicitly defined for it, but I suspect it’s for clarity: if every function could be used that way, some people might be tempted to do away with . and ()s, making code much harder to parse. Or maybe that avoids some syntactic ambiguities. Can anyone confirm?)

2 Likes

I was just writing a DSL and thought about this. Came here to suggest it, lo and behold you already did!

I think it would be a good addition, honestly. It matches the idea of many of kotlin’s features! It makes your code feel more natural!

However it should probably only apply to functions that return Boolean for obvious reasons.

There’s a feature request about that, KT-5351, and at the moment 38 people there including me agree with you :slight_smile:

5 Likes