Skip to content
AgileLogics
4 min read

Scope

Prerequisites: Functions

Scope is the region of code where a name can be used. Every pair of curly braces creates a new scope.

Real-world analogy: scopes are nested rooms. From an inner room you can see into the rooms around it, but people outside can't see in.

Example

const val TAX_RATE = 0.2         // top level: visible everywhere in the file

fun total(price: Double): Double {
    val tax = price * TAX_RATE    // inner code can see outer names
    return price + tax
}

fun main() {
    println(total(100.0))

    if (true) {
        val message = "inside"
        println(message)
    }
}
120.0
inside
  • TAX_RATE is declared at the top level of the file, so every function can use it.
  • tax exists only inside total.
  • message exists only inside the if braces.

Using a name outside its scope is a compile error:

fun main() {
    if (true) {
        val message = "inside"
    }
    println(message)
}
error: unresolved reference 'message'.

Shadowing

An inner scope can declare a name that hides an outer one. IntelliJ warns about it ("Name shadowed"), because it's easy to confuse the two — usually it's better to pick a different name.

Keep scope small

Declare values close to where they're used, and pass values into functions as parameters rather than reading many outside variables. Mutable top-level variables in particular make programs hard to follow.