0

In the below nested loop:

for i in 0..<2 {
    print(i)
    for i in 0..<2 {
        print(i)
    }
}

the output should be:

0
0
1

However it produces:

0
0
1
1
0
1
I can't find anything referring to the scope of the index (i) in apple documentations. I would appreciate any reference or explanation from an official source.

6
  • 2
    why don't you change your inner loop var name Commented Dec 22, 2016 at 22:23
  • Well, excusing how blatantly poor the code is (nobody would do this, we all know that), the results show exactly what you are thinking - each loop has it's own variable scope. I'm surprised too. If this is indeed what you're thinking, a few thoughts: (1) What if instead of "for i in" you did for arrayElement in" with nested arrays of the same type? Does this same behavior happen? (2) You've done your research for sure, is this worthy of a swift.org query/request? BOTTOM LINE: Good catch on the behavior! Now, unless you really wish to confuse your "future self" use a different index. :-) Commented Dec 22, 2016 at 22:27
  • 1
    Why is it surprising that each loop has its own variable scope? The loop introduces a new variable binding. You could also do for let i which makes that more obvious. Commented Dec 22, 2016 at 22:27
  • this question is not about a problem I am facing in a code. It is to understand why swift is considering i as two different vars. that will not be the case with Java for example. Commented Dec 22, 2016 at 22:29
  • @dfd thank you for the comment, I was reading this repo and found a nested loop with the same index name :) , I agree it was confusing.github.com/vinceyuan/WatchTicTacToe/blob/master/… Commented Dec 22, 2016 at 22:35

2 Answers 2

1

When you define a loop for X in ..., you're defining scope that exists during each iteration and a constant that exists in that scope. I can't find explicit documentation of scope except for in the case of do {} but the documentation does assume scope is created and destroyed in loops when speaking of things like the guard declaration. In practice, this is what the scope for i in a single loop looks like.

// Scope that i doesn't exist in.

for i in 1..<2 {
    // Scope that i exists in.
}

// Scope that i doesn't exist in.

When defining a nested scope (which your inner for loop is), you have the ability to redefine variables and constants. This is what happens when you define i in the loop declaration. Inside the inner loop, the compiler looks outward through the scope for definitions.

In the case of i, it looks in the inner loop and finds it. In the case of print, the identifier used, it looks in the inner loop, the outer loop, any containing fiction, then class, then module, then imported modules until it finds Swift.print.

Sign up to request clarification or add additional context in comments.

2 Comments

How is the example explaining the i in the outer loop is invisible in the inner loop?
I still am surprised. Sure, my formal education was between 1976-98. But this is not something at all intuitive. Explicit documentation is needed. That said, (and please if doc is found, add it) I like your explanation. Up-voted.
0

Loop variables are scoped to the body of the loop. Swift allows shadowing of local variables, so the nested loop gets a brand-new variable called "i", and loses access to variable "i" from its outer scope.

4 Comments

That's what i was thinking about. But is there an official source to this?
Commenting here because you have more rep. This behavior feels very wrong. (It's true though.) What I mean to say is when I learned about variable scope some 40 years ago, loops didn't operate that way. While I understand that my comment here is mostly opinion, this is something I would not expect - in fact, a certification (yeah yeah, MSFT) I received 20 years ago tested exactly on this and at the very least needed "more" to communicate to everyone that you are not tromping on things with each loop. Very surprising behavior to me....
@iShaalan That has to be in the language reference. I don't have access to it at the moment (I'm on a mobile device) but it should be in the chapter about loops.
@dfd Coming from C background myself, I find this behavior grossly counterintuitive.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.