A < b < c

I was checking out the try Kotlin website when I saw this example:
https://try.kotlinlang.org/#/Kotlin%20Koans/Conventions/In%20range/Task.kt
Since I knew how much Kotlin has tried to improve Java in terms of readability I was expecting something like this to work: return start < d <= endInclusive.
Which is obviously much more readable than return start < d && d <= endInclusive.
As far as I know c, c++ and python also support such syntax in different ways.

I am suggesting perhaps it would be nice to support such syntax in ascending order:
a < b == c <= d
Not sure about descending order:
a > b == c >= d
Or mixed:
`a < b == c >= d

Note that == has lower precedence than comparison operators. Descending and mixed ordered syntax are not ambiguous but I’m not sure about their readability so perhaps they can be allowed with a quick fix warning(which changes semantics because of exception possibility…)

And in the rare case someone truly needs to compare Booleans:
(a < b == c) <= d

I’m not sure about the implementation complexities though…

Kotlin way to do so is start in d..endInclusive. It gets some time to get accustomed to, but in the end it is much more concise and could be easily overridden for custom objects.

I’m guessing this only works for inclusive comparison and when you have 3 operands?

It work just fine with non-inclusive comparison like a in b until c. One can define his own range class and infix function to check if needed (you can see ranges documentation for additional examples). The important point is that you do not need to introduce new language constructs to express this situation. This allows a lot of flexibility when using not numbers, but some custom objects, also it allows future improvement of language through the libraries without touching the language itself.

The way I see this, a <= b <= c is much more easily readable than b in a..c or a <= b < c much more easily readable than b in a until c plus it covers more than 3 operands plus it can cover a < b <=c and equality checks anywhere in between. comparison and equality checks can be overridden by overriding compareTo() or equals() by custom objects so I don’t see your point about flexibility there.
But the most important thing that makes me think this is a good idea is that when your write a < b < c you almost never mean to compare the result of a < b as a Boolean with c. This is a waste of possibly useful syntax.

Again I must emphasize I’m no expert in language design and implementation. But I highly doubt this will result in some code or library migration.

I personally got used to the a in b .. c syntax. IMO some people prefer one syntax some the other.

Agreed, this would be very useful if you have 3 or more comparable objects and have to check that they appear in a special order, but than this would also lead to syntax like this a < b == c <= d in which way I would think that it means a < b && b == c && c <= d which currently due to operator precedence it wouldn’t (breaking change).
The thing is, how often do you actually have 3 or more comparable objects with such defined qualities?
In my experience most of the time I check whether a single value is inside of a specified range, maybe inside multiple ranges, but I don’t compare multiple values against each other like this often

The point about flexibility is that all of the things you describe can actually be done inside the language without introducing any new features, you would just need to add ranges with an open start / end.
Adding this feature to the language where one operator changes it’s behavior based on how many operators you chain makes the language more complex and more error prone without adding much benefit. You would have to learn arbitrary rules like, you can only do this in ascending order, you can not or you can not use == inside of those chains.
This would just lead to confusion and decrease the readability of the code.

1 Like