Skip to content
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: Infer type on ranged for loops from the type of the range values instead of defaulting to usize #14704

Closed
BanchouBoo opened this issue Feb 22, 2023 · 4 comments

Comments

@BanchouBoo
Copy link
Contributor

Ranged loops defaulting to usize only makes sense when it's paired with a slice or array iteration, in any other case there isn't really any good reason for it that I can think of, especially when the values used aren't comptime_ints.

The following is the behavior I would expect from the types on ranged for loops:

// i is comptime_int, and thus won't work because this is a runtime loop
for (0..10) |i| {}

// i is a comptime_int, but works fine because the loop is inlined
inline for (0..10) |i| {}

// i is a u8
for (0..@as(u8, 100)) |i| {}

// i is a usize
for (slice, 0..) |item, i| {}

// i is a u16
for (@as(u8, 0)..@as(u16, 10000)) |i| {}

// i is a u8, since it's required for the start of the range to be a lower number than the end of the range it's guaranteed that i will not overflow
// if it's later decided that decrementing ranges will be allowed, then i should instead be a u16
for (@as(u16, 0)..@as(u8, 100) |i| {}

In discussion on this topic in the discord, the idea of putting the type on the capture was also floated:

for (0..10) |i: u32| {}

But I think basing it off the type of the values used in the range itself makes much more sense, personally.

There was also a suggestion to infer the integer type to the smallest type that will fit the range when using comptime_int to define the range.

// i is u4
for (0..10) |i| {}

But requiring an explicit type in there somewhere feels more "correct" to me, and I feel that the uses where you know both ends of the range at comptime and aren't iterating over an array or storing the number in a constant somewhere that can be give a type are pretty uncommon in practice.

@wooster0
Copy link
Contributor

I think we definitely need some way of having control over the index type. While looking for whiles in my code and looking which ones I can replace with the new syntax, I realized most of my indices are not usize and it would actually make my code worse and actually increase memory usage because a lot of my range loops only go over so much data and my index types have important meaning that would now be lost with the new syntax.

@Srekel
Copy link

Srekel commented Mar 20, 2023

Just to add my "+1", I just stumbled onto this issue in actual code, here was my workaround.

        for (0..3) |lod| {
            const lod_u4 = @intCast(u4, lod);
            world_patch_manager.WorldPatchManager.getLookupsFromRectangle(state.heightmap_patch_type_id, area_old, lod_u4, &lookups_old);

The lod is a u4 because it doesn't need to be more. Since the for loop pretty clearly/explicitly fits inside a u4, I think it should work fine to just pass it in. Just like it does when you explicitly pass in, say, 3, you don't need to do @intCast(u4, 3).

Code here (at the time of writing only 0..1 due to being WIP):
https://github.com/Srekel/elvengroin-legacy/blob/main/src/systems/terrain_quad_tree.zig#L1257

@andrewrk andrewrk closed this as not planned Won't fix, can't repro, duplicate, stale Apr 10, 2023
@BanchouBoo
Copy link
Contributor Author

Any chance we can get some elaboration on why this has been closed?

@andrewrk
Copy link
Member

I'm not accepting language proposals at this time. I've already considered this and rejected it. If you tried to implement your proposal, you would see the problems with it. Unfortunately I don't have time to explain in detail why nearly all of the ~463 open proposals will be rejected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants