I am having some trouble creating functions returning const or mutable stuff without duplicating code. This affects the way to write iterators as well.
Let’s take a simplified image example.
Sometimes I want readonly access, sometimesj mutable access.
How to handle this?
And while writing this thread I was wondering about the 3d function. Is that legal, the image being const and returning a mutable slice?
In this case, we only need get_line_slice_3 because the pixels field is just a slice (pointer).
*const Image only prevents modifying the Image object itself through that pointer. Constness is not transitive through the pointer stored in the pixels field, so it is perfectly valid for get_line_slice_3 to return a mutable []Pixel .
Of course, if pixels were an array instead of a slice, things would get a lot trickier.
But that’s why it’s an issue. For array field just a little meta programming on the input constness is enough. Here the problem is how should I encode constness for my “slice wrapper” type.
Zig has power here that library authors don’t have, because []u8 silently casts to []const u8, while MyMutSlice wont cast to MyConstSlice
The way I usually handle this is by only writing the const version of the function. Then, you can handle the mutable case by using @constCastat the callsite. The rule here is that if you pass in mutable data, then you’re allowed to use @constCast on whatever you get back.
I tried your approach at some point, but in the end I decided it wasn’t worth the hassle. In practice const/non constness is relatively easy to track down, compared to eg ownership where the type system don’t help. We already have type safety to track host memory vs accelerator memory, so I didn’t want to multiply the nber of combintions.
IMHO a self: anytype is vastly different to a different to an arg: anytype, because in normal code the . operator ensures it is constrained already and ZLS handles it fine.
Yeah I agree, technically that’s not my favorite solution either, nowadays I prefer to have dedicated “View” inner types, and I usually try to operate on group of things, and therefore this isn’t necessary, but yeah not really readable with the comptime wizardry, although you could remove the function signature typeinfo and have it inside the isConstPtr
Yes I just stumbled upon this exact problem and ended up with two versions of the function for simplicity and because I only needed one function to be duplicated. Might look into more complex solutions if there are more functions showing up