Suffix notation

I think it would be really useful if Kotlin supported suffix/postfix operators.

Given a Degree class:
data class Degree(val value: Double)

one could define a suffix function like so:
suffix fun Double.deg() = Degree(this)

which could be use as follows:
val angle = 90.0 deg

which would get compiled down the equivlant code:
val angle = Degree(90.0)

This is similar to the user-defined literals in C++11.

3 Likes

I doubt the use case warrants a new language feature, considering that extension properties come very close already:

data class Degree(val value: Double)

val Double.deg: Degree 
  get() = Degree(this)

val angle = 90.0.deg
3 Likes

True, but you could say the same for infix functions.

val flag = 1 shl 4

Could just as easily be expressed with

val flag = 1.shl(4)

The best argument I can muster in support, I suppose, is that infix and suffix functions open up the potential to write more elegant and readable code, which naturally fits in with many DSLs.

Isn’t that one of the major selling points of Kotlin?

2 Likes

Point taken. I guess I’m not a big fan of this kind of opt-in alternative syntax in general, as it puts more burden on users (“Did this method support infix syntax?”, “Should I be using infix syntax here?”) and leads to less uniform code. Perhaps either-or would be better, i.e. infix/suffix functions are considered operators and can’t use normal function syntax.

1 Like

My understanding is that Scala has these and is removing them, because it causes weird side effects and problems.

True, but I believe Scala’s suffix notation suffers because, like their infix notation, it’s something implicitly available to all unary and nullary methods. This causes issues because it can be difficult and non-intuitive to predict how Scala will parse the statement, especially if could have also been an infix notation.
E.g. The statement foo bar baz could be foo.bar().baz() or foo.bar(baz) or who knows what else.

I don’t believe Kotlin would have this issue to the same degree, if even at all, because it sensibly requires a function to state whether its an infix or not. This gives us more control of the DSL, as we can predict and design how it will be used.

It was also a wise choice to make the infix an operator, so it has an explicit precedence.

Just thought about another alternative would be to define a singleton object degrees that had plus and minus operator functions so you could instead say something like this:

  val angle1 = degrees +90
  val angle2 = degrees -90

but I would not be opposed to postfix functions.

I agree, units of measure are a very valid use case!
Because some functionality is already available for infix calls, it’s is already possible to write this:

val date = 15 april 2017

That is valid Kotlin code given the function:

infix fun Int.april(year: Int): Calendar {
    val out = Calendar.getInstance(TimeZone.getTimeZone("Europe/Zurich"))
    out.set(year, Calendar.APRIL, this)
    return out
}

Of course, a small dot does not look like a huge problem:

discountAfter[3.days] = 10.percent

But the code would look better without it.

I believe, postfix notation can have sense, e.g. by physical units:

val x = 1 m 
val y = 2 m
val s = x * y

This is an old thread and I would wager there isn’t much to new that would help suffix style function calls get over the minus 100 points.

They add a lot of potential for confusion when the current options with extensions and operator overriding are so effective for use cases of units. If there is a way to avoid adding the language feature but still get the kind of expressiveness for units then that would be preferred.

Here’s two libraries that give an idea of what’s possible to express now:

There’s also some unit discussion in other topics.
https://discuss.kotlinlang.org/t/units-of-measure/

There’s also the option for units to use some kind of compiler plugin. Compiler plugins have become supported in Kotlin since that discussion. Here’s a link to some stuff mentioned in the discussion:

1 Like

Thank you very much for your detailed answer. My interest in this topic arose while trying to develop own Kotlin library for correct work with typical physical units. Unfortunately, I did not find one that meets my requirements. That is why I decided to program my own.
Today this library is in Alfa version. However, I plan to complete it in the short term.
Here is the link: GitHub - vsirotin/si-units: Kotlin function and objects for working with SI units like meter, second, as well as currencies and general units like percent.