> For the complete documentation index, see [llms.txt](https://amartyushov.gitbook.io/tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://amartyushov.gitbook.io/tech/programming-languages/kotlin/effective-kotlin.md).

# Effective Kotlin

## Limiting mutability

1. Immutability makes it easier to parallelize the program
2. References to immutable objects can be cached as they not going to change

### Read-inly properties

```kotlin
class BlaBla {
    val oneTime = calculate() // once during class instantiation calculate() is executed
    val eachTime: Int
        get() = calculate() // !!each time calculate() executes for eachTime access

    val name: String? = "Alex"
    val secondName: String = "Mart"

    val fullName: String?
        get() = name?.let {"$it $secondName"}

    val fullName2 = name?.let {"$it $secondName"}

    fun calculate(): Int {
        println("Calculating...")
        return 42
    }
}

fun main() {
    val instance = BlaBla()

    if (instance.fullName != null) {
        println(instance.fullName?.length) // smartcast doesn't work here as
    }                                      // fullName has custom getter
        // it means compiler still assumes instance.fullName can be null 

    if (instance.fullName2 != null) { // smartcast works here
        println(instance.fullName2.length)
    }
}
```

### Mutable and read-only collections

<figure><img src="/files/GoK3fSqUXtN0EQ8Tnkku" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Down-casting read-only collections to mutable should never take place&#x20;
{% endhint %}

Instead do this

```kotlin
val list = listOf(1,2,3)
val mutableList = list.toMutableList()
mutableList.add(4)
```

### Copy in data classes

```kotlin
class User(
    val name: String,
    val surname: String
) {
    fun withSurname(surname: String) = User(name, surname) // each time new object is cretaed
// but this is immutale, which is good
// on the other hand it is too much to create such function for each class field    
}
```

```kotlin
data class User(
    val name: String,
    val surname: String
)
var user = User("Alex", "Mart")
user = user.copy(surname = "other")

// copy function which comes out of the box for data classes is recommended way to
// keep objects immutable, instead of making fields var
```
