Bill Yan
Bill Yan

Reputation: 3468

What's the benefit of range based for loop over traditional c style for loop?

I'm implementing my own programming language and getting stumped on what for loop syntax to choose.

It seems that all latest and cool languages are using the range based for loop. I googled hard in order to understand its pros and cons, the the only answer seems to be cleaner and cooler. While I can be cool by flowing the trend. I can't convince myself it's better than the c style for loop.

I think it is great to support shortcuts like for(:), foreach, for ... in..., but shouldn't the old c style for loop be supported as a universal fallback?

for(int i =0;i<len;++i) {}

Because it is so flexible and can easily handle all possible cases. To me, it's an example of "less is more".

With it, I don't need to search for answers like :

using range based for loop for iterating on a sub range

Reverse Range in Swift

https://www.dotnetperls.com/range-swift

Skip 1st Iteration of Range-Based For Loops

I only need to remember one syntax to achieve everything. For example, the following snippet implements a run length encoding algorithm. You can update the index of the for loop in a sub while loop. You don't need to progress with a constant step. You don't have to pre-define the looping behavior.

// CPP program to implement run length encoding
#include <bits/stdc++.h>
using namespace std;
 
void printRLE(string str)
{
    int n = str.length();
    for (int i = 0; i < n; i++) {
 
         // Count occurrences of current character
        int count = 1;
        while (i < n - 1 && str[i] == str[i + 1]) {
            count++;
            i++;
        }

        // Print character and its count
        cout << str[i] << count;
    }
}
 
int main()
{
    string str = "wwwwaaadexxxxxxywww";
    printRLE(str);
    return 0;
}

Is the range based loop mainly for language ergonomics?

but aren't these ugly? You end up typing more to achieve the same.

for i in stride(from:5,through:1,by:-1) { print(i) } // 5 4 3 2 1

for (n, prime) in primes.enumerated() {}

Edit: After writing the initial question, I faintly remembered that swift seemed to support c style for loop at the beginning and removed it later. After googling that history, I found https://github.com/apple/swift-evolution/blob/master/proposals/0007-remove-c-style-for-loops.md , which has some of the reasoning behind it. I don't think "not very Swift-like." is very logical though ...

Upvotes: 2

Views: 560

Answers (1)

Ben
Ben

Reputation: 65

It definitely seems that C-style loops are powerful enough for any use case. So why not use them?

One reason that comes to mind is safety: detaching the index from the collection enables a whole host of mistakes. For example, the classic array-index-out-of-bounds errors: perhaps the programmer forgot that your language is 0-indexed, or they incremented the counter too many times, or maybe something else went wrong — I'm sure most programmers have had an experience of the sort. In contrast, it's impossible to mess up (in that manner) when you have some sort of range-based syntax.

(Of course, you could always decide that it's the programmer's job to avoid those mistakes. With great power comes great responsibility, after all! Many languages have decided to take this route, or have at least allowed it. I know of at least one very successful example.)

On the point of "ugly:" I actually find C-style loops to be uglier than many alternatives. For one, it often ends up being additional boilerplate — for i in range(1...5) { … i … } is much more direct than for (i = 0; i < range(1...5).length(); ++i) { … range(1...5)[i] … }. And elaborate counter manipulation schemes are, as I mentioned, quite easy to screw up. As someone with a more functionally-inclined disposition, I'd be much more comfortable with a scheme that's more provably correct.

Speaking of functional inclinations: C-style loops might not fit with the paradigm of your language. In many languages, a 'for loop' isn't even a natural concept! If your primary structure is the s-expression (as in Lisp), a range-style loop (aka map) is much more natural than a for loop. (If you want to be really pure, mutating counter variables also isn't natural.) I've noticed this tends to arise in programming languages with a strong focus on structural recursion (think LISPs, Haskell, Pyret, etc). And structural recursion is fantastic because it's very well-defined, especially when compared to erratically-incrementing loops.

At this point the question "but why bother with a functional paradigm?" might arise… but that's been discussed extensively elsewhere.

Upvotes: 0

Related Questions