swiftkotlinfunctional-programming

Variable capture: How variables behave in function closures


I have this code, and I would like to know if the value of the variable x is captured by the function at the time it is defined, or if the function captures a reference to the variable itself (or is there something else)?

Would there be a difference in how everything is processed if x was a val?

// Kotlin
var x = 1
fun f(y: Int) = x + y // Function adds 1 to a given Int

x = 2
val y = 3
val z = f(x + y) // Calls f with argument of 5
// z now maps to 7
// Swift
var x = 1
func f(_ y: Int) -> Int {return x + y} // Function adds 1 to a given Int

x = 2
let y = 3
let z = f(x + y) // Calls f with argument of 5
// z now maps to 7

So whenever we call function f, we're going to evaluate its body { x + y } in the environment the function was defined. And when we defined this function, we had an environment where x == 1.

So function f always adds 1 to its argument, no matter where it is called. That is the rule. (This rule is for let / val, not var I assume?)

My question is around the function closure in relation to the var.

Just give me a detailed explanation of this (following the scope chain to locate variables in memory), thanks.


Solution

  • In both Kotlin and Swift using var means the closure captures a reference to the variable itself, while val/let, which are immutable, capture the value of the variable at the time of the closure's creation.

    Following the example you've given, if you had used val instead you'd be left with the following:

    val x = 1 
    val g = { x + 3 }  // Closure g captures the value 1
    x = 2 // this would cause compilation error 
    
    val z = g()    // z will be 4 (1 + 3)