Compare the scope functions let, run, with, apply and also.
All five run a block with an object in context. They differ in how the object is referenced (it or this) and what they return (the object or the lambda result).
let:it, returns the lambda result. Used for null checks and transformations.run:this, returns the result. Configuration plus computation.with:this, returns the result. Grouping several calls on one object.apply:this, returns the object. Object configuration.also:it, returns the object. Side effects such as logging.
val user = User().apply {
name = "Ada"
age = 36
}
val upper = user.let { it.name.uppercase() }
Choose based on chaining needs rather than habit: use apply at the end of a builder chain, also for side effects, and let when you need the result. Avoid nesting them so deeply that this becomes ambiguous, and keep blocks short.