6

Is general concept of closures in Swift similar to closures in Javascript, or do they use same word "closure" but with different rules? Specifically, (to quote my friend) closure in Javascript is "crystal ball that can peer only where it was created".

So, in Javascript this code works:

var outside = 5;
function test() {
 alert(outside); // returns 5
}

Does that mean in Swift, if I create closure in any of the possible ways, it will have access to all local variables at same scope right where closure was created?

(I've looked at wikipedia definition of closure in programming, but it felt too vague - specifically, what values is closure keeping track of)

Rudi
  • 2,450
  • 5
  • 26
  • 37
  • The wiki definition seems pretty clear to me -- "a closure is a function or reference to a function together with a referencing environment—a table storing a reference to each of the non-local variables (also called free variables or upvalues) of that function. A closure—unlike a plain function pointer—allows a function to access those non-local variables even when invoked outside its immediate lexical scope." – elclanrs Jul 10 '14 at 21:44
  • In that JS example, wouldn't "outside" be local variable, though? – Rudi Jul 10 '14 at 21:45
  • @Rudi Local to the outer function (the one that contains the entirety of the code you show), but not local to `test`. –  Jul 10 '14 at 21:46
  • I don't know about Swift, but I've seen other languages with that copy the outer variables into the local scope instead of referencing the outer environment like JS does, and they refer to it as closures. This would seem like an important difference. I don't know if they're using the term properly or not though. – cookie monster Jul 10 '14 at 21:47
  • @delnan thank you, that makes more sense! – Rudi Jul 10 '14 at 21:48
  • @cookiemonster i'd be interesting to find out how swift does it. Copying variables would really change how things are implemented. – Rudi Jul 10 '14 at 21:49
  • I read the Swift manual when it came out, but I don't recall. I think I'll review it to see. – cookie monster Jul 10 '14 at 21:50
  • 1
    [From this page](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-XID_112) it seems that the value is copied into the closure if not modified, otherwise is referenced. So its behavior would seem to be like JS. Close to the bottom, start reading at: *"Because it does not modify amount, incrementor actually captures..."* – cookie monster Jul 10 '14 at 22:01

1 Answers1

0

Swift closures capture local variables so fulfil your "crystal ball that can peer only where it was created" requirement.

Because of the difference in scoping, Swift does not suffer from the same problem of using closures within loops

JavaScript closure inside loops – simple practical example

The Swift equivalent:

var funcs: [()->()] = []

for i in 0...3 {
  funcs += {
    println(i)
  }
}

for i in 0...3 {
  println(funcs[i]())
}

Yields the result 0, 1, 2, 3

Community
  • 1
  • 1
ColinE
  • 68,894
  • 15
  • 164
  • 232
  • 1
    *"...unlike JavaScript closures can be defined as anonymous functions..."* JavaScript anonymous functions (all JS functions for that matter) create a closure. – cookie monster Jul 10 '14 at 21:52
  • 1
    @cookiemonster very good point. What I meant is that Swift closures do not require a `fund` or `function` keyword so are more concise – ColinE Jul 10 '14 at 21:53
  • Ah, yeah JS function syntax is verbose... [for now](http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax). :-) – cookie monster Jul 10 '14 at 21:55
  • 1
    There is a lot of cool new stuff coming in JS. Exciting times! – ColinE Jul 10 '14 at 21:59
  • 2
    "Swift does not suffer from the same problem of using closures within loops" It's not a fair comparison because in JavaScript you're using a regular for loop that re-uses the variable, but in Swift you're using a `for..in` loop that makes a new iteration of the variable. If you use a regular for loop in Swift that re-uses the variable, the same issue occurs. – newacct Jul 11 '14 at 02:45
  • The example provide doesn't work, a working example: https://gist.github.com/mariorodriguespt/f1379a73f4e70b0acac4 – Mário Apr 02 '15 at 07:47