Make infix functions safe to be applied to nullable receivers

Take the following (dummy) function as an example:

fun <A, B> toPairOrNull(a: A?, b: B) : Pair<A, B>? = if (a != null) a to b else null

One could argue that another way to write it could be:

fun <A, B> toPairOrNull(a: A?, b: B) : Pair<A, B>? = a?.to(b)

I was wondering if there any plans for Kotlin to automatically support applying inline functions (like Pair's to) to nullable receivers? From the user point of view I think the syntax should follow the “Safe” cast operator. Something like:

fun <A, B> toPairOrNull(a: A?, b: B) : Pair<A, B>? = a to? b

(appending a question mark to the infix function name would make it “Safe” - like in the as case).

Thoughts?

Inventing a new syntax to replace x?.foo(y) with x foo? y doesn’t really seem like it’s worth it. Every new syntax has to be learned by all Kotlin programmers, has to be supported in the IDEs and compiler(s) and so on.

I would argue that even infix functions aren’t really necessary and could have been left out. But they make sense as replacement for operators. But having a special syntax for infix functions that return null if the left operand is null isn’t really necessary. You could theoretically write a function

infix fun <A : Any, B> A?.to_(b: B) = this?.to(b)

and you could write x to_ y instead of your x to? y. Doesn’t really seem to be worth it, though.

1 Like

Thanks for your input @Jonathan.Haas!

I understand (and agree) that this functionality isn’t necessary but, as you said, neither were the infix functions and still, they made it to the language.

The point I’m trying to make is that, since we already have infix functions and things like the “Safe cast operator” perhaps it wouldn’t be that farfetched to add something like what I proposed.

One major upside of that would be that this solution would be universal so it would be understood by everyone (passed the point where they learned it in the first time). This would save each us from writing their own “alternative” solutions (like using underscores to indicate nullability) that would differ from developer to developer.

I’m still uncertain that this would make sense for every use of infix functions though. I can certainly see a stronger case for functions (like Kotlin’s own public infix fun <A, B> A.to(that: B): Pair<A, B>) that are meant to be used using the infix notation: one could certainly write "leandro".to("nunes") but I don’t think anyone does.

I know that such a feature would take a lot of effort to be supported (and I simply see it as a nice-to-have).

Thanks again!
Leandro

Another reason why your proposal might be a bad idea is that an infix function is supposed to look like both operands have the same priority. Why would x to? y return null when x is null, but not when y is null? With x?.to(y) it’s obvious with the question mark, that the case that x is null is handled specifically because of the x?.

In addition, there is nothing that stops you from writing an infix function that accepts a null receiver (and handles it in some appropriate way)

Also the ? in the operator as? has slightly different meaning in Kotlin, hence it would introduce an inconsistency.

1 Like