Enums with ranges

const pub Grade  = enum(u8) {
F = 0..60,
D = 60..70,
C = 70..80,
B = 80..90,
A = 90..97,
Aplus = 97..100,

or since people like the idea of ranged checked ints

pub const Percent = enum(u8) {
_ = 0..101,
// and potentially  bad_value = 999 and allow gaps 

in safe builds they could perform valid checks when assigned to, and in non-safe builds they could elide them.

There is an existing discussion on this in allow integer types to be any range · Issue #3806 · ziglang/zig · GitHub

I wold never use them, so dont care too much, but I didnt like any of the porposals. They all add stuff to the language that i think are unnecessary. This just uses current concepts and doesnt really need anything new like @range or new types.

with this you can put all errno values in it, plus have a speciial success value, add a user defined error range, etc. and dont need to learn anything new.

Your proposal creates a new set type that doesn’t behave like an enum yet reuses the name. It’s not reusing existing parts as none of this currently exists in zig. The linked talks about partition which is the closest thing to that you’ve proposed here.

its basically an inexhaustible enum with some constrain t checking on assignment in non-safe builds - that it. (this isn’t meant for catching violations during compile time, just runtime – i meean you could propagate constants into the constraint checks at compile time and do that but not necessry for first pass).

Plus this also gels well with the merging enums like error sets and now you have new enum with both constaint sets.

Yes but that’s not an enum but a partition. Enum members are still single integer values and this proposal declares them as ranges. What is the result of @intFromEnum(Example.foo) as an example?

This is not an enum but something else.

1 Like

It extends enum, but it is still similar to an inexhaustible enum. Just now a tag can have multiple values (@intFromEnum would give you value back out).

Under your interpretation an inexhaustible enum of not a enum either but a partition or an int or some new name, yet we still use the enum construct for them. The default case has the range of all other values not already included, and the default case can already have gaps! This just allows the rest of the enum to have similar characteristics to the default. We use the same term for slightly different things all the time in programmiing (think const, static, inline in C/C++, etc)

Yes, it extends the concept of enum a little in a way similar to how exhaustible enums did. We don’t need a whole new ttype (then you also have to deifne all the interactions, you reserve another symbol (a not so rare one either), etc.) These concepts arent fixed , we are allowed to grow or shrink them as they fit the domain. Zig and c++ attach methods to structs unlike their predecessor but nobody says those arean’t structs.

All the proposals create too much complexity for so little gain. Is zig trying to replace C or C++? Yes, the enum concept grows a little, but some of proposals want to create new @ builtings, new keywrods, etc… those are all uneeded. zig already has all that right now.

Which value would it give for const E = enum { a = 0..10, b = 10..20 } in @intFromEnum(E.a)? This is the literal .a tag and not constructed from @enumFromInt(...). In this case the result would need to be implementation defined as there is no good answer to the above question given that 0…10 is not a valid value in zig nor does this proposal provide one.

Avoiding the introduction of a new separate kind of type to “not be C++” is not a good motivation for this to modify enum and I would argue that overloading enum to have more than it already does will increase the complexity of comptime code.

1 Like

I would personally much rather introduce a separate range concept, and try to make all current uses of ranges (loops, switch cases, others) use this new concept. There are enough complications about a range (does it include the start value? the end value? what is the underlying integer type? can you iterate over it in ascending order? descending? skipping elements? etc.) that I feel it deserves its own treatment.


Good questions. You aleady can’t do that with the default label in enums, you would only be able to use enum tags that are singularly values. Like I said, this only extends the behavior of the default label to other lablel. That is it. All this behavior already exists in non-exhaustive enums in the default case, not it just also exists for mutli-valued labels.


This exists in the loops as syntax. It would need to become a firrst class type, which is good idea regardless. Optimizations to this would often apply to iterators in general too

zig already has enums that aren’t traditional enums and structs that aren’t tradition structs. I think you are too hung up on the name, but the code and concepts overlap significantly.

I’m not a fan of the range syntax, but I think that ship has sailed. You can’t do anything interesting in it and it is only given back to you as a usize, only goes acsending, no striding, isn’t a type, etc… It sucks.

I’d like it is zig had a true range iterator and type, but i think that has all been rejected already by core.

1 Like