← Back to Kotlin Course | Chapter 10: Extension Functions & Properties | Lesson 6 of 6

Extension Function Best Practices

Best practices for extensions are the good habits that keep your bolted-on abilities clear and easy to find later, instead of scattered and confusing.

Naming Extensions Clearly

A good extension function name should read naturally at the call site and clearly describe what it does, avoiding vague names that could be confused with unrelated behavior.

Example: Naming Extensions Clearly

markup
fun String.isValidEmail(): Boolean = this.contains("@") && this.contains(".")

// Entry point: execution of the program starts here
fun main() {
    // Print `"[email protected]".isValidEmail()` to the console, with a trailing newline
    println("[email protected]".isValidEmail())
    // Print `"not-an-email".isValidEmail()` to the console, with a trailing newline
    println("not-an-email".isValidEmail())
}

Avoiding Surprising Side Effects

Because an extension function looks exactly like a real member function to the caller, it should behave predictably -- avoid extensions that silently mutate shared state in surprising ways.

Example: Avoiding Surprising Side Effects

markup
fun MutableList<Int>.addIfPositive(value: Int): Boolean {
    // Return `if (value > 0) {` from this function
    return if (value > 0) {
        add(value)
        true
    // Otherwise, run this branch
    } else {
        false
    }
}

// Entry point: execution of the program starts here
fun main() {
    // Declare a read-only variable `numbers`, set to `mutableListOf(1, 2)`
    val numbers = mutableListOf(1, 2)
    numbers.addIfPositive(5)
    numbers.addIfPositive(-3)
    // Print `numbers` to the console, with a trailing newline
    println(numbers)
}

Scoping Extensions to Specific Types

Writing an extension against the narrowest type that makes sense (rather than a very broad type like Any) keeps it relevant and avoids cluttering autocomplete suggestions for unrelated types.

Example: Scoping Extensions to Specific Types

markup
fun Collection<Int>.sumOfSquares(): Int = this.sumBy { it * it }

// Entry point: execution of the program starts here
fun main() {
    // Print `listOf(1, 2, 3).sumOfSquares()` to the console, with a trailing newline
    println(listOf(1, 2, 3).sumOfSquares())
}

Grouping Related Extensions Together

Organizing extension functions that relate to the same type or feature area into one clearly named file makes them easy for other developers (and your future self) to find.

Example: Grouping Related Extensions Together

markup
fun String.truncate(maxLength: Int): String =
    if (this.length <= maxLength) this else this.take(maxLength) + "..."

fun String.titleCase(): String =
    this.split(" ").joinToString(" ") { it.capitalize() }

// Entry point: execution of the program starts here
fun main() {
    // Print `"kotlin programming language".titleCase()` to the console, with a trailing newline
    println("kotlin programming language".titleCase())
    // Print `"This is a long sentence".truncate(10)` to the console, with a trailing newline
    println("This is a long sentence".truncate(10))
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Adding extension functions with overly generic names on very broad types (like Any), risking name clashes and confusing autocomplete suggestions.
  2. Putting extensions with side effects that surprise callers, since an extension looks just like a normal member function at the call site.
  3. Scattering extension functions across many unrelated files instead of grouping related ones together for discoverability.
Chapter Summary
  • Keep extension functions focused, well-named, and scoped to as specific a type as makes sense.
  • Avoid extensions with confusing side effects, since call sites cannot tell an extension apart from a real member at a glance.
  • Group related extension functions together in a clearly named file so they are easy to discover and maintain.
  • Prefer extensions for genuinely reusable, general-purpose helpers rather than one-off logic specific to a single use case.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.