Object immutability


Hi everyone,

I’m relatively new to Kotlin, and I’ve already rewritten big portions of production code to it because it’s a really awesome language. As of now, I’d only miss a recursive immutability modifier, like const in c++.

There’s a small discusson on that in the slack’s #language-proposals channel, and thanks to some contributions (mostly arguments against my proposal) I’ve been able to develop it better, so I’ll give it a try here.

That modifier would be able to target

  • Methods/functions: to tell they are read-only. In the scope of such methods, all members are treated like vals so they can’t be set, and only their read-only methods can be called.
  • Variables: to identify them as immutable. Right now we have val to tell the reference cannot change, but the value is not readonly and you can perfectly mute the object it points to. By having that modifier we would not be able to call any setter nor any non-readonly function

Real immutability is a pretty important feature, Kotlin itself already has had to implement it for containers (with my proposal containers would be able to go back to having only 1 implementation handling both mutable and immutable references)

But there’s a catch in here: with only that (which would already be a pretty awesome language feature for a better typing and restrictions), we cannot assert that a immutable object will not be modified in another thread that has a mutable reference to it. In my opinion that’s not a good enough reason, but we could still do something about it in runtime.

Every object could have an atomic flag stack telling whether it’s in readonly state or not.
When an object becomes referenced as immutable, that flag would be pushed, and when leaving that reference’s scope it would be popped.
Then, whenever a mutating operation is performed on an object with that flag set, an exception would be thrown.
This could be optimized to have pretty much no overhead, but still it would be nice if it’s only enabled with a runtime flag.

What do you think about it?

EDIT: The compiler should be able to detect by itself when a method is readonly or not, so the method modifier could be just a hint for the compiler to throw an error when a method has that modifier but it’s mutating the object.

EDIT 2: With all that in mind, we could have a new concept: immutable classes. These would not need any locks whatsoever because they would be immutable by definition. We could have an immutable class modifier which asserts that for any class. Clear example: String.


I like the idea of an immutable class modifier, as this would definitely make some code better and easier to understand. The problem I see is inheritance. Should immutable classes be sealed all the time and if not, how do you prevent a child class from mutating the object? Obviously in Kotlin you can children of immutable classes to also be immutable, but what if someone in Java is trying to inherit from an immutable class.

The same problem exists the other way round? Should immutable classes be able to inherit from mutable classes? How can you than ensure that they are really immutable? I don’t think there are any good ways to solve this problems if it is even possible (on the JVM that is). I don’t think this would be possible as long as JVM byte code does not support immutability on an object level.


Initially, the immutability modifier applies only to references/variables. Then, as an extra idea, we can have immutable classes as well. Regarding that, I would vote to force children to be immutable if the parent is, but that definitely needs lots of thinking.

As of java interop, I didn’t really think a lot about it. I would do like with null safety, which is basically that there are some annotations helping intellij to warn java coders, but with no way to enforce anything. And the other way around, if something comes from java, runtime checks would have to come in place.


I just don’t understand how this should work? I explained why immutable classes would not work. The problem I see with the immutable references/variables is that this would be impossible to do on the JVM. I don’t see any way how this could be solved in any way. I understand you idea with a flag for each object but again, this would only work for parts of the code which do not use any third party libraries.


Again, as with null safety, there’s no way to ensure it in java, but that didn’t stop the feature from being implemented. Look, a fragment of the documentation stating why a npe could still occur:

Java interoperation:
Attempts to access a member on a null reference of a platform type;
Generic types used for Java interoperation with incorrect nullability, e.g. a piece of Java code might add null into a Kotlin MutableList, meaning that MutableList<String?> should be used for working with it;
Other issues caused by external Java code.

The same would apply to immutability. Adopting it would become a very slow process, but eventually most libs will have their kotlin version :slight_smile:


I don’t agree. With Null safety you know when an npe can happen, as they are restricted to platform types. That would not be so with immutability as any open class could become mutable at any time. There is no way of writing runtime checks against it, which would leave you with the same problem you had before.

I’m not saying I don’t like the idea. I just think it wont happen :frowning:

As to the libs having a kotlin version. I am 100% sure that as long as Kotlin will not fully replace Java, most big libraries will stay Java and this includes a lot of the standard library (maps, lists, etc) as JetBrains will not reimplement them in Kotlin if they are already existing in Java.


Immutable classes could be translated as final for java. And again, what you’re exposing is only one of the so many problems java interoperability would bring to the feature, but as I said it could still exist and make kotlin-only projects very strongly typed.

Kotlin is so close to be the perfect language, and by seeing its path with kotlin native and javascript, I would be so sad to see that the JVM limitations are blocking its evolution.


Hi @pcasafont,
your proposal is interesting, but I am really sceptic about it.

But there’s a catch in here: with only that (…), we cannot assert that a immutable object will not be modified in another thread that has a mutable reference to it. In my opinion that’s not a good enough reason, but we could still do something about it in runtime.

I agree with you, for this reason you should not mix up immutability with read-only.

Every object could have an atomic flag stack

You need an atomic counter?

When an object becomes referenced as immutable, that flag would be pushed, and when leaving that reference’s scope it would be popped.

Two atomic operations for each variable?

This could be optimized to have pretty much no overhead

How it is possible optimize atomic counters without disabling it?

What do you think about it?

C++ const keyword is an unfortunate feature, API design become harder and read-only doesn’t mean immutable.
Immutable data class looks as safer choice.


The second part of my proposal is only to be able to assert the immutability is true along threads. If we decide to give up this assertion, it wouldn’t be necessary.

However, let’s talk about it. When I said it could be optimized it’s because of several facts:

  • Some variables can be statically proven to be thread-local. These wouldn’t need any runtime checks.
  • Variables/values created as immutable will have no possible way to be ever referenced as mutable. These won’t need checks either.
  • The counter (yes, you’re right, I meant a counter) will only be updated when moving from mutable to immutable context.

Another way to solve all this would be to make casting from mutable to immutable impossible, and only allow objects which were directly created as immutable. That would make the feature thread-safe at compile time, but in certain cases we would have to copy objects just to pass them to functions that take only immutable parameters.

And there’s another decision I’m not sure about. Should immutability be totally recursive or just down to the class fields’ level? A clear example of just one level of immutability are containers: we may be interested on having immutable containers holding mutable objects… or the other way around.

Decisions, decisions… thanks for your feedback. By the way, how do you distinguish immutable from read-only?


This is probably the safer and cheaper way.

val mutable: MutableList<Int> = mutableListOf(1, 2, 3)
val readOnly: List<Int> = mutable
val immutable: List<Int> = Collections.unmodifiableList(listOf(1, 2, 3))


Indeed, and it would be a very good start.

I’d say they are conceptually the same, both readOnly and immutable are restricted to changes on compile time by kotlin, while the last one also holds runtime checks because java has a different interface for list and it needs runtime checks.

While they both have different implementations (the readonly is certainly mutable when it’s referenced to as a MutableList), here we encounter that interesting fact: one can cast from immutable to mutable containers with the current design, but with my proposal that wouldn’t be possible.