Overloading 'and' and 'or' operators

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.

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.

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

1 Like

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)

1 Like

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?

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

1 Like

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.

1 Like

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.

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

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

I am a new Kotlin user and I do not agree.

I think there is two consistens solution.

I can accept both but I prefer B.

A) Do not respect operator precedence.

So a | b & c has the same result (and execution order) as a or b and c (where or, and are infix functions).

In this case a || b && c must return the same result as a | b & c because this is the consistent behaviour.

For now a || b && c = a || (b && c) and != (a || b) && c so this solution breaks existing code behaviour.

B) Respect operator precedence.

So a | b & c has the same result as a || b && c.

This behaviour is the same as the Java one so this is the expected behaviour.

In this case a or b and c does not equal with a | b & c (where or, and are infix functions).

This is not a problem because infix functions are not operators.

This solution breaks existing code behaviour because of the existing operators like +, *

UPDATE: I checked plus and times. It seems they respect operator precedence so it is not a breaking change. Maybe this topic is too old and contains outdated info. Sorry.

The boolean conversion overload is a great idea, something like toBoolean which would be invoked when an object is used in a context where a boolean is expected, similar to how toString works.

This is essentially asking for “truthiness” in Kotlin. If there’s more people wanting to reply or discuss this idea we should probably create a separate topic.

1 Like