Kotlin does not currently support the ability to define custom symbolic operators. Many functional languages like F#, Haskell, OCaml provide this functionality which can lead to considerably more concise code as well as the ability to define DSL within the context of the language. An example use cases would be something like this:
infix fun <IP, R> (() -> IP).forwardCompose(f: (IP) -> R): () -> R {
return { f(this()) }
}
private val add5 = {(i: Int)-> i + 5 }
private val multiplyBy2 = {(i: Int)-> i * 2 }
val add5andMultiplyBy2 = add5 forwardCompose multiplyBy2 // add5 andThen multiplyBy2
The forward compose function would be significantly more concise if I could define it with symbol operators (â>>â) as such:
infix fun <IP, R> (() -> IP).>>(f: (IP) -> R): () -> R {
return { f(this()) }
}
private val add5 = {(i: Int)-> i + 5 }
private val multiplyBy2 = {(i: Int)-> i * 2 }
val add5andMultiplyBy2 = add5 >> multiplyBy2 // add5 andThen multiplyBy2
Only being limited to the existing symbolic set, presents some challenges for general code readabily IMO. Would it be possible to add support for custom symbol operators definitions?
I just read through that thread, doesnât look like there was ever any agreement regarding the forward pipe operator. Other than itâs another language feature that requires some modifications to the compiler and adds complexity for maintainers.
My post here is specifically not to introduce new operators to the core language, but to give developers the ability to define symbolic operators. Forward pipe is one example of an operator that is very handy.
I donât think this would be a good idea. There have been many situations where developers are confused about the precedence of inline functions (in context of binary infix functions) since there is no way of setting the precedence. That would also be true for custom operators but with far worse results as you would expect them to behave like operators. Itâs easy to say all infix functions have the same precedence, but to force this for all custom operators would be problematic.
This feature would immediately lead to binary operators being added (if not to the stdlib than to a lot of other libraries) but without proper operator precedence. I donât think this would end well.
That said if you can come up with a system to fix this (across multiple libraries) âŠ
But even if problems like this could be overcome, I still donât like this idea. Ok, maybe kotlin could do with binary operators and maybe even a pipe operator (even though I still donât think it needs either), but a way to define random operators? I think itâs a bit overkill. Just imagine all math libraries adding dozens of operators for all random maths functions. Why not add ** for pow and while we are at it â for the square root and who knows what for random other functions. Ok, most sensible programers wouldnât add most of those, but wouldnât it be nice (just for this specific domain) to have this one thing as an operator instead of a function?
On main goal of kotlin is to be readable and I donât think the ability to define custom operators helps in this regard. I know this is a bit over the top and more like a worst case by someone abusing the idea, but it explains why I donât think itâs good.
Every operator is something new each programmer has to learn and unlike function names they donât explain what they do.
Yes, this works but the back-ticks are a bit annoying when building DSLs. But does allow us to define symbolic operations. The argument for not using the back-ticks comes from functions being first class citizens of the language where functions could have any name.
Iâm not familiar enough with how Kotlin interacts with Java to say if thatâs possible but would be nice to have.