Closed
Description
We currently allow loops (for/while) to have an else expression on them. The code within this expression is evaluated only if the loop runs in its entirety.
for (values) |value| {
if (value == s) {
// do something
break;
}
} else {
// do the fallback thing
}
I argue that this type of loop and flow is uncommon enough that we should remove this construct completely. The else on a loop could be fairly non-obvious if not familiar with the construct and it adds another thing to the language which is non-essential.
Given that we only should have "Only one obvious way to do things", here are some other ways of replicating the above control flow:
A simple flag
var found = false;
for (values) |value| {
if (value == s) {
found = true;
break;
}
}
if (found) {
// do the fallback thing
} else {
// do the fallback thing
}
Write a function
fn findItem(comptime T: type, values: []const T, item: T) bool {
for (values) |value| {
if (value == item) {
return true;
}
}
return false;
}
if (findItem(...)) {
// do the fallback thing
} else {
// do the fallback thing
}
Use a named block in place of a function
const found = block: {
for (values) |value| {
if (value == item) {
break :block false;
}
}
break :block true;
}
if (found) {
// do the fallback thing
} else {
// do the fallback thing
}
Are there any other specific use-cases I'm missing? How many times has this been done in the stdlib? I know I've never used this construct.