-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: C-style for loop #8292
Comments
@zzyxyzz for-loops are used for iterating and while loops for more complex control flow. Further more one wants to have the initial condition/variable (as precondition of the loop) being explicit (if it is not trivial from the iterator) for simpler code reasoning. |
Ideally, yes. But Zig's highly specialized
Sometimes. But note that most of the items you mention are already allowed in Zig, and the resulting long lines are not uncommon in base. This proposal only adds the ability to pull in the loop variable into the same line. This should work fine for most loops, but if the line gets too long, it can be broken up.
I don't quite get this point, could you clarify? |
loop (var it = foo.iter(); it; it = it.next()) |val| { If Did you mean something like: loop (var it = foo.iter(); it.next(); _ = {}) |val| {
…
} … |
@pfgithub While trying to find a better one, I ran into a bit of a problem: Apparently the updating and unwrapping variant of pub fn countChildren(node: *const Node) usize {
var count: usize = 0;
var it: ?*const Node = node.next;
while (it) |n| : (it = n.next) {
count += 1;
}
return count;
} If Zig disallowed combining unwrapping and update clauses that wouldn't make much of a difference: pub fn countChildren(node: *const Node) usize {
var count: usize = 0;
var it: ?*const Node = node.next;
while (it) |n| {
count += 1;
it = n.next;
}
return count;
} And using pub fn countChildren(node: *const Node) usize {
var count: usize = 0;
loop (var it: ?*const Node = node.next; it; it = n.next) |n| {
count += 1;
}
return count;
} I'm not yet sure how much this affects this proposal. In any case, I should have mentioned that the initializer and updater are supposed to be optional, just like in C. So there's no need for loop (var it = foo.iter(); it.next() ;) |val| {
// ...
} |
After thinking about it some more, there are really just two common cases where this proposal might be seen as an improvement over the status quo: var i: usize = 0;
while (i < len) : (i += 1) {
...
}
// -->
loop (var i: usize = 0; i < len; i += 1) {
...
} and var it = map.iterator();
while (it.next()) |kv| {
...
}
// -->
loop (var it = map.iterator(); it.next() ;) |kv| {
...
} There's a tradeoff here between readability and prevention of variable leakage. Which one you prefer is probably a matter of taste. Either way, this proposal no longer seems like a sufficiently large improvement to me, so I'm going to close it for now. |
The main benefit of the classic for-loop in comparison to the current while loop, is that the iterating variable goes out of scope when the loop is over. Given Zig's lack of shadowing having a variable that automatically goes out of scope is nice. Yes, you can definitely simulate this by surrounding the while loop with a block, but let's be honest, that's even less readable. |
I do very much agree that it can happen that the optimiser is not smart enough to elide the variable, which can be an annoying performance loss. (I have no deep understanding of C/C++ semantics, so take this with a grant of salt.) However, I think that reusing the same variable is a more bad idea for searchability and review. |
This is a proposal to give Zig's
while
loop a little nudge in the direction of feature parity with C'sfor
loop, the lack of which is a frequently bemoaned (#5070, #8019, #358, #472, #8030).Doing this would:
Proposed syntax:
The
loop
keyword was chosen mostly for its lack of baggage:while
would clash with C convention andfor
with Zig. But this is ultimately just a suggestion and open to alternative proposals.The loop would support unwrapping just like the current
while
:A simplified variant could also be permitted:
...at which point the
while
keyword might be dropped entirely.The text was updated successfully, but these errors were encountered: