0

Why does for loop require var while for..in does not allow use of var?

for loop

for var index = 0; index < 10; i++ {

}

for..in loop

for index in "test" {

}

instead of:

for var index in "test" {

}
9
  • 1
    Now that I reread and better understand the question, I'm voting to close as primarily opinion based. Only the language designers can answer this question accurately... anything else is speculation... but there's good historical precedent for things working this way. Commented May 29, 2015 at 0:47
  • 1
    In that case all language features are opinion-based, and this is a good reason "opinion-based" criteria should be removed from the site. The knowledge shown in the answer below is 100x more useful than your comments so far. Even if they force a let in it, it still answers my question of why var is not needed in for..in. Commented May 29, 2015 at 0:57
  • 1
    The facts presented in the answer are that the index is immutable (and cannot be anything but immutable). But this still isn't the question you're asking. You're asking why var (and also let which is perfectly valid in your "traditional" loop example) are not necessary. And as I've pointed out, it's still purely opinion based as to why it's for index in someArray versus requiring for let index in someArray. Only a language designer can chime in on the actual question asked here (why the let isn't used). Commented May 29, 2015 at 0:59
  • 1
    OK, I can see why you term it opinion-based now. Even then, I still believe there is benefit in discussing why a language feature is the way it is. Commented May 29, 2015 at 1:05
  • 1
    It's funny to see nhgrif is voting to close as primarily opinion-based while he does it himself as well... Commented May 29, 2015 at 1:54

2 Answers 2

3

The Swift documentation sums it up pretty nicely:

index is a constant whose value is automatically set at the start of each iteration of the loop. As such, it does not have to be declared before it is used. It is implicitly declared simply by its inclusion in the loop declaration, without the need for a let declaration keyword.

In other words, the variable used in a for/in loop can only be a constant; thus, there's really no need to require that let be used.

The variable(s) used in a "traditional" for loop, however, can be variables or constants, so var or let is required. (Generally, they will be variables, but it is possible to use a constant in a for loop.) They can also be declared outside of the for loop (i.e., before it) and still used in the for loop. Because of this flexibility, you are required to declare it as a constant or variable.

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

Comments

2

The compiler expands for x in 0..<5 to the following:

var g = (0..<5).generate() {
while let x = g.next() {
    // Use x in loop body
}

Every time around the loop, x is a freshly declared variable, the value of unwrapping the next result from calling next on the generator.

Now, that while can be rewritten in this fashion:

while var x = g.next() {
// use x here
}

I guess for this reason, for...in doesn't support the var syntax for declaring the loop counter so that it doesn't give you the wrong impression that x is mutable.

5 Comments

Do you mean in the let case, x is a new instance each time through?
@Boon, Yes, x is assigned to the next() value of the generator each time. In my opinion, I think the Swift designers didn't want to include the let or var keyword for the loop counter to avoid misconceptions about what can be done with it i.e. modify it which is a strict no-no.
Bruce, just to be sure, x is a new instance only if the instance returned by next() is struct or enum, right? In the case of class, x will be the same instance, right?
@Boon, g, which is returned by the generate() method is the same instance throughout the course of the loop but I think x is freshly created for every single iteration. I don't think the compiler reuses the same x instance. Having said that, I'm not sure whether it would be dependent on next() returning an instance of class/ enum/ struct.
enum/struct is copied and class is passed by reference. So my thought is if an object of class type is returned from next(), x won't be a new instance.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.