Overloading 'and' and 'or' operators


#1

Hi,
I’m really enjoying learning Kotlin.
Are there any plans to allow overloading ‘and’ and ‘or’ operators?
For creating DSLs that support boolean expressions it would be super handy.


#2

Overloading ‘and’ and ‘or’ is recommended against in most languages because short-circuiting is lost, which changes the usual symantics of the operators.

This would apply to any such overloading support in kotlin unless it is/was implemented in a special way (I.e. as a boolean conversion overload instead).

Depending on the purpose of the type(s) in question it may be better to define a small boolean property with an appropriate name.


#3

Overloading of || and && is not planned, but | and & are on the table


#4

If it helps you any I just prefer to use infix functions with word names as and/or

eg.
infix fun <T> T?.or(other: () -> T?): T? = if(this == null) other() else this

Could actually work even better than && / || for DSLs (matter of taste perhaps)


#5

I did try infix functions but then operator precedence cannot be specified.

Thinking about it | and & are what I am looking for rather than || and &&. If this was implemented would precedence be maintained when overloading?


#6

Operator precedence is overrated. Use parens. You don’t see lispers complaining.


#7

Operators always use the same precedence; it doesn’t matter whether a user-provided overloaded implementation or the built-in one is used. This applies to + and * in the current version, and will also apply to other operators if we extend the set of operators that can be overloaded.


#8

I always thought of operators in Kotlin as sugar for certain functions. Not enough realising that operators have a different precedence than functions.

fun main(args: Array<String>) {
    val a = F("a")
    val b = F("b")
    val c = F("c")
    val d = F("d")
    
    println(a.plus(b).plus(c).plus(d)) // prints "[[[a, b], c], d]"
    println(a.plus(b) + c.plus(d))     // prints "[[a, b], [c, d]]"
}

class F(val s:String) {
    operator fun plus(f:F): F = F("[$s, ${f.s}]")
    override fun toString() = s
}

Nothing wrong of course, just an observation.


#9

This is great news. I look forward to & and | being supported. I couldn’t find a ticket for this. Is there one already created?


#10

For anyone else looking the ticket is https://youtrack.jetbrains.com/issue/KT-1440