Why Kotlin wouldn't compile with var mutableSetOf or mutableListOf

Hi Guys,

As I was testing with the key word 'mutableSetOf ', I found something interesting. I’m posting this since I believe this is related to the discussion made here.

In my code, I’m trying to add a ‘random’ number generated between 1 - 25 to my ‘mutableSet’. Now, if I declare my MutableSet variable to ‘var’ it won’t allow me to add/remove any numbers inside the set itself:

fun experiment(): Int
{
    var counter = 0
    val setVariable1 = mutableSetOf<Int>()
    **// Won't compile if setVariable1 is declared as 'var' !!!**

    do
    {
    setVariable1 += Random.nextInt(25) +1
    ++counter
    }while(setVariable1.size < 25)
    return counter
}

I understand that val/var here will only determine the character of the variable ‘setVariable1’ itself, so I don’t understand why the compiler won’t let me add anything even though the set instance itself is declared mutable(= mutableSetOf). For what it’s worth, I got the same result when using mutableListOf as well.

Hope my question makes sense. Thanks in advance for the help!

*Edit: I’m also posting a link somewhat related to this topic. Even after reading this, however, I still couldn’t come up with an answer to my question.

[Link]

List item

Kotlin has operators for working with collections and mutable collections (List, Set, etc.) which enable easier adding elements. For example, if you are using immutable list, but want to add new element, you need to declare var list, and when you call += operator this will mean that you assign new immutable list to your variable, that has all elements from original list plus one new.

var list = listOf(1,2,3)
list += 4

Now, if you want to use mutable list, you can do same, but usually you dont want to create new mutable list when you add new element.

So, in order to prevent confusion is the new list going to be created, or is current list just going to be extended, you cannot use var, mutableList and += operator.

2 Likes

In any case it’s probably better to use setVariable1.add instead of using +=. That way there is no confusion about += in the first place.

set1 + set2 is ok for sets since it clearly creates a new set. set1 += set2 is less clear. Does it modify set1 or does it create a new set and assign it to the variable set1. For readonly sets it’s obviously the first but unless the type declaration is right next to it, it’s still sometimes hard to tell. Sure it’s actually forbidden for mutable sets but that’s a less well known fact.
Therefor I tend to not use += for collections. It’s bad for readonly collections since it will always create a copy which can have very bad performance impacts (especially in loops) and it’s bad for mutable collections because the code is harder to read.

2 Likes

Thanks. This all makes everything clear now.
This was my first time posting here and I’m glad I did that. Much appreciated!

1 Like

I’m glad we could help and welcome to the comunity :wink:

2 Likes

Just spoted this. I want to point out that List<T> is not an immutable list in kotlin. It’s a readonly list. In many cases this doesn’t matter but it in some areas this can lead to confusions. If you need an immutable list there are special libraries for that.
I know it’s not really relevant here but there have been enough topics raised here in the last few years (because of this mistake) that I feel it’s important to correct this.

3 Likes

Thanks Wasabi375 for your clarification!

1 Like