# Why Kotlin functions returning List do not use immutable list implementation?

**URL:** <https://discuss.kotlinlang.org/t/why-kotlin-functions-returning-list-do-not-use-immutable-list-implementation/29646>\
**Category:** Language Design\
**Created:** [December 20, 2024, 3:36pm UTC](https://discuss.kotlinlang.org/t/why-kotlin-functions-returning-list-do-not-use-immutable-list-implementation/29646 "2024-12-20T15:36:45Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![msevcenko](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/msevcenko/32/10989_2.png) [@msevcenko](https://discuss.kotlinlang.org/u/msevcenko)\
**Post date:** [December 20, 2024, 3:36pm UTC](https://discuss.kotlinlang.org/t/why-kotlin-functions-returning-list-do-not-use-immutable-list-implementation/29646/1 "2024-12-20T15:36:45Z")

</div>

Such as those readily available in Java,e.g. `List.copyOf(collection)`, or similar native implementation. In particular, I would expect, that `toList()`, calling on a collection or a sequence, would return an immutable snapshot of that collection or sequence, and calling `toList()` again would return the same instance.

A related side question - what is the idiomatic solution to frequent situation, when you get `List` in a constructor, and you want to store (a copy) of this (seemingly unmodifiable) list?

In Java, I would go with something like this:

```auto
class Service {
    private List<String> list;

    public Service(List<String> list) {
        this.list = List.copyOf(list);
    }
}

```

In Kotlin, I can do either:

```auto
class Service(val list: List<String>) {
    ...
}

```

or

```auto
class Service(list: List<String>) {
    val list = list.toList()
    ...
}

```

The problem is, that the first solution is unsafe (must make an assumption that the caller would not modify the list), while the second solution is inefficient (every such call copies elements around and creates another snapshot of the collection).

Which solution would you use? I would consider the first solution as idiomatic, and would use in my code where I can make that assumption.

However, if I would like to create some independent library, that makes no assumption about outer environment, I would need to resort to the second solution, wouldn’t I?

Or is there something better? Isn’t this a design flaw of the Kotlin collection framework?

---

<div class="post-metadata">

**Author:** ![LSafer](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lsafer/32/9366_2.png) [@LSafer](https://discuss.kotlinlang.org/u/LSafer)\
**Post date:** [December 20, 2024, 3:57pm UTC](https://discuss.kotlinlang.org/t/why-kotlin-functions-returning-list-do-not-use-immutable-list-implementation/29646/2 "2024-12-20T15:57:34Z")

</div>

I guess they have gone to the trust everything path.

The constructor of `JsonObject` in `kotlinx-serialization-json` takes any arbitrary `Map<String, JsonElement>` as its backing map.

But you are right! why trust here but not in `toList()` implementation 🤔

I guess this is why they thought about these:

- [GitHub - Kotlin/kotlinx.collections.immutable: Immutable persistent collections for Kotlin](https://github.com/Kotlin/kotlinx.collections.immutable)
- [https://youtrack.jetbrains.com/issue/KT-43871](https://youtrack.jetbrains.com/issue/KT-43871)

---

<div class="post-metadata">

**Author:** ![Landei](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/landei/32/9407_2.png) [@Landei](https://discuss.kotlinlang.org/u/Landei)\
**Post date:** [December 20, 2024, 4:20pm UTC](https://discuss.kotlinlang.org/t/why-kotlin-functions-returning-list-do-not-use-immutable-list-implementation/29646/3 "2024-12-20T16:20:33Z")

</div>

I agree that there should be a better solution, but I think the reason that this is not addressed is that typical Kotlin code doesn’t contain many mutable lists, especially not passed around as arguments. E.g. if I see in code reviews someone use a mutable list just to fill it more easily (which means “more like I used to do it in Java” in this context), I try to convert it to immutable style, or at least use `buildList{...}`. So if you and your team follow best practices, you can assume that lists are really immutable. It’s not ideal to rely just on conventions, so you have to use the `toList()` solution when you want to be 100% safe.

---

<div class="post-metadata">

**Author:** ![msevcenko](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/msevcenko/32/10989_2.png) [@msevcenko](https://discuss.kotlinlang.org/u/msevcenko)\
**Post date:** [December 20, 2024, 4:50pm UTC](https://discuss.kotlinlang.org/t/why-kotlin-functions-returning-list-do-not-use-immutable-list-implementation/29646/4 "2024-12-20T16:50:29Z")

</div>

So you think that the idiomatic Kotlin solution of this usecase is just to trust the code. That is, if someone just proclaims MutableList to be a List, pretend that this list is unmodifiable. Not great, you would probably get away with this technique in most cases, but I am afraid it could backfire sometimes.

In the good old Java days, I have seen pedantic implementations that would copy a snapshot of the input, and if they should expose the list, they would do so using the unmodifiable wrapper. I thought that these days are gone starting with Java 10 where new unmodifiable lists were introduced, which provide a clean solution to this problem.

So there is a better solution, you could just implement Iterable.toList simply as:

```auto
public fun <T> Iterable<T>.toList() = java.util.List.copyOf(this)

```

That would create immutable snapshot as requested, and you would get that idempotency optimization for free.

Problem is that this construct does not support null values, maybe another reason was that Kotlin collection framework library needs to be compatible with Java prior 10.

So more robust solution would be reimplementing these immutable collections in Kotlin, I think it wouldn’t be too much work. I would consider such solution much better than the current one.

---

<div class="post-metadata">

**Author:** ![msevcenko](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/msevcenko/32/10989_2.png) [@msevcenko](https://discuss.kotlinlang.org/u/msevcenko)\
**Post date:** [December 20, 2024, 4:56pm UTC](https://discuss.kotlinlang.org/t/why-kotlin-functions-returning-list-do-not-use-immutable-list-implementation/29646/5 "2024-12-20T16:56:20Z")

</div>

Btw, the contract of Java 16 `Stream.toList`, _requires_ that the implementation of the returned list must be unmodifiable.

> The returned List is unmodifiable; calls to any mutator method will always cause UnsupportedOperationException to be thrown.

And AFAIK the default implementations of stream return the immutable snapshot.

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [December 20, 2024, 5:04pm UTC](https://discuss.kotlinlang.org/t/why-kotlin-functions-returning-list-do-not-use-immutable-list-implementation/29646/6 "2024-12-20T17:04:46Z")

</div>

Have you had a look at `kotlinx.collections.immutable` yet? I believe their `ImmutableList` is exactly what you want!

---

<div class="post-metadata">

**Author:** ![msevcenko](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/msevcenko/32/10989_2.png) [@msevcenko](https://discuss.kotlinlang.org/u/msevcenko)\
**Post date:** [December 20, 2024, 8:54pm UTC](https://discuss.kotlinlang.org/t/why-kotlin-functions-returning-list-do-not-use-immutable-list-implementation/29646/7 "2024-12-20T20:54:39Z")

</div>

> Have you had a look at `kotlinx.collections.immutable` yet? I believe their `ImmutableList` is exactly what you want!

Well, yes, it seems it is exactly that. This is the very same example I provided:

> <https://github.com/Kotlin/kotlinx.collections.immutable/blob/master/proposal.md#use-cases>

My point, however, was having this feature out-of-the-box, or idiomatic practice, not as some (more or less non-) standard extension. After all, you need to use `.toImmutableList()` to opt-in for this feature.

But yes, it is very close to what I want. Thanks for the link!

I also wonder what means that this is a “proposal”, and since it is in kotlinx package, it is (or soon will be) after all some sort of standard extension?

---

<div class="post-metadata">

**Author:** ![clovisai](https://avatars.discourse-cdn.com/v4/letter/c/a9adbd/32.png) [@clovisai](https://discuss.kotlinlang.org/u/clovisai)\
**Post date:** [December 22, 2024, 5:24pm UTC](https://discuss.kotlinlang.org/t/why-kotlin-functions-returning-list-do-not-use-immutable-list-implementation/29646/8 "2024-12-22T17:24:14Z")

</div>

If I understand correctly, the main reason is that `Collections.unmodifiableList` change referential equality and the Kotlin team didn’t want the syntax to change referential equality invisibly.

This question is asked once in a while, and there is a youtrack ticket: [https://youtrack.jetbrains.com/issue/KT-66257/Compiler-option-for-protected-passing-of-collections-to-Java](https://youtrack.jetbrains.com/issue/KT-66257/Compiler-option-for-protected-passing-of-collections-to-Java)
