A local function is declared inside another function to keep helper logic near its only use. It reduces duplication without filling a class with narrowly scoped methods. section 3.6
Listing 3.13 Extracting a local function to avoid repetition
class User(val id: Int, val name: String, val address: String)
fun saveUser(user: User) {
fun validate(user: User, #1
value: String,
fieldName: String) {
if (value.isEmpty()) {
throw IllegalArgumentException(
"Can't save user ${user.id}: empty $fieldName")
}
}
validate(user, user.name, "Name") #2
validate(user, user.address, "Address")
// Save user to the database
}
Extracts repeated user-validation code into validate, a helper nested inside saveUser. section 3.6
A local function can access parameters and variables from its enclosing function, so validate does not need a separate User parameter. The helper receives only the changing value and field name while still using user.id for the error message. section 3.6
Listing 3.14 Accessing outer function parameters in a local function
class User(val id: Int, val name: String, val address: String)
fun saveUser(user: User) {
fun validate(value: String, fieldName: String) { #1
if (value.isEmpty()) {
throw IllegalArgumentException(
"Can't save user ${user.id}: " + #2
"empty $fieldName")
}
}
validate(user.name, "Name")
validate(user.address, "Address")
// Save user to the database
}
Simplifies validation calls by capturing user from saveUser instead of passing the whole object explicitly. section 3.6
Use local functions when you need to:
- Group extracted steps under the function that owns their purpose. section 3.6
- Eliminate small, local cases of duplicated code without adding class methods. section 3.6
- Keep helper visibility confined to the enclosing function. section 3.6
When the logic becomes useful beyond one function, move it into an extension function instead. User.validateBeforeSave keeps validation outside User while providing a clearer call site. section 3.6
User validation before saving
saveUser defines validate locally, checks the user's name and address, and throws an exception containing the user's identifier when either field is empty. section 3.6

