[Proposal] Logical augmented assigment operators


#1

Hi there,

either I am missing out something, or it simply isn’t there. Sorry if I just missed it.

In Kotlin we have augmented assignment operators with +, -, /, * and %. This is great. We can do this:

var counter = 0
for(i in 0..10)
{
    counter += 2 * i
}

But there are no augmented logical assignment operators (available in Java), to do this:

var everythingFine = true
var individualOks = arrayOf(true, true, true, true, true, false, true)

// Check if every individual is fine
for(ok in individualOks)
{
    everythingFine &= ok
}

println(everything fine) // prints ~$ false

This would be great at least for (the ones, Java supports, too)

  • |= or
  • &= and

Additionally, you could think about adding

  • !&= not and
  • xor= exclusive or

They could be defined this way:

operator fun andAssign(other: Boolean) { this = this && other }

operator fun nandAssign(other: Boolean) { this = !(this && other) }

operator fun orAssign(other: Boolean) { this = this || other }

operator fun xorAssign(other: Boolean) { this = this xor other }

operator fun norAssign(other: Boolean) { this = !(this || other) }

Thanks for your interest :slight_smile:
Cheers,
Gem


#2

Off-topic: There is a function to test if a predicate holds for all elements of an iterable: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/all.html

Your example code can also be written as:

val everythingFine = individualOks.all { it }

#3

Thanks. I know. Just wanted to give a very simple example for the augmented operators :wink:


#4

nand, nor and xor are not operators, regarding your proposal I don’t see the use case.


#5

Even if they are not operators, they will be useful. At least &= and |= should be beyond question.


#6

I might be wrong here, but don’t &= and |= normally represent the bitwise operation and not the boolean operation. This would make kotlin very inconsistent, having bitwise assignment operators but no normal bitwise operators.
So I don’t think they should be a part of kotlin as long as we don’t have bitwise operators. Whether they are a good idea is another discussion (and I’m not sure if I like them or not).


#7

That’s the Java notion. To keep it consistent &&= and ||= could be an alternative.


#8

I strongly believe Java is using the bitwise Boolean operators for &= and |=.


#9

What about a generic assignment operator for infix operators?

val a: Foo
val b: Bar
a fn= b
class Foo{
    infix fun fn(b: Bar): Foo
}

#10

Do you have actual example where you use it more than twice in one piece of code?


#11

I use it quite often, to check whether requirements in a complex context are met. I think the most useful aspect is shortness and tidier code. It’s the same like writing

a1 = a1 + a2

instead of

a1 += a2

#12

Checks do not usually require assignment. Could you give a reference to actual piece of code?


#13

I’ll let you know, as soon as I stumble upon it again. Just noticed, that I had to replace lots of &= and |= occurences when porting my projects from Java 1.8 to Kotlin. Mostly simple assignments like:

private boolean teamFit = true;

public void OnAttack(Monster defender, int damage)
{
    teamFit &= defender.isFit()
}

#14

I don’t believe that a &&= b notation is a good idea.
If it would have short-circuiting behaviour, it may be not obvious that f() will not be evaluated in a &&= f() when a is false.
If there’s no short-circuiting behaviour, a &&= f() won’t be the same as a = a && f().