Skip to content

Remove loop-else expressions #1004

Closed
Closed
@tiehuis

Description

@tiehuis

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions