Kotlin

Lesson 04

Scope function intent

Use scope functions when the receiver and return value match the reader's expectation.

Good Code

src/main/kotlin/reviews/ReviewFactory.kt
fun buildReview(input: ReviewInput): Review {
    val title = input.title.trim()
    val review = Review(title = title, score = input.score)

    // also records the created review without replacing the return value.
    return review.also { createdReview -> audit.created(createdReview.id) }
}

Bad Code

ReviewFactory.kt
fun buildReview(input: ReviewInput) =
    input.let {
        Review(it.title.trim(), it.score).apply {
            // Nested receivers hide whether id belongs to input or Review.
            audit.created(id)
        }
    }

Review Notes

What to review

Good Code

The good version names the intermediate Review and uses also only for the audit side effect.

Bad Code

The bad version nests let and apply, so it, this, and id need extra mental tracking before a reviewer can see the returned value.

Takeaways

  • Kotlin scope functions should reveal whether code transforms a value, configures an object, or records a side effect.