user102008
user102008

Reputation: 31313

Swift curried function behaves differently from expanded version

I have a curried function in Swift:

func counter(var val: Int)() -> () {
  val++
  println(val)
}

According to this answer it should be equivalent to this:

func counter(var val: Int) -> (() -> ()) {
  func curryFunc() {
    val++
    println(val)
  }
  return curryFunc
}

However, when I run the following code:

let x = counter(3)
x()
x()

with the first one, I get 4, 4; whereas with the second one, I get 4, 5.

I am using the release Xcode 6.0.1.

Upvotes: 2

Views: 137

Answers (1)

Antonio
Antonio

Reputation: 72760

The difference is that in the first version the body of the curried function is a normal function implementation, whereas in the 2nd case there's a closure. As stated in the documentation:

Closures can capture and store references to any constants and variables from the context in which they are defined.

In your case, val is captured, and retained among consecutive calls.

Addendum - if you want to have your 2nd function to behave like the curried one, you should store the parameter in a variable declared inside the function body:

func counter(val: Int) -> (() -> ()) {
    func curryFunc() {
        var unretainedVal = val
        unretainedVal++
        println(unretainedVal)
    }
    return curryFunc
}

The captured value val doesn't change, so the function keeps a reference to its original value.

Upvotes: 3

Related Questions