# Avoiding duplication of code for readonly or mutable access

**URL:** <https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519>\
**Category:** Help\
**Tags:** language\
**Created:** [September 7, 2026, 10:03am UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519 "2026-09-07T10:03:50Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ericlang](https://ziggit.dev/user_avatar/ziggit.dev/ericlang/32/8515_2.png) [@ericlang](https://ziggit.dev/u/ericlang)\
**Post date:** [September 7, 2026, 10:03am UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/1 "2026-09-07T10:03:50Z")

</div>

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?

```zig
pub const Image = struct {
    width: u32,
    height: u32,
    pixels: []Pixel,

    // readonly
    pub fn get_line_slice_1(self: *const Image, y: u32) []const Pixel {
        const offset: u32 = self.width * y;
        return &self.pixels[offset..offset + width];
    }

    // mutable
    pub fn get_line_slice_2(self: *Image, y: u32) []Pixel {
        const offset: u32 = self.width * y;
        return &self.pixels[offset..offset + width];
    }

    // what about this??
    pub fn get_line_slice_3(self: *const Image, y: u32) []Pixel {
        const offset: u32 = self.width * y;
        return &self.pixels[offset..offset + width];
    }

}

```

---

<div class="post-metadata">

**Author:** ![npc1054657282](https://ziggit.dev/user_avatar/ziggit.dev/npc1054657282/32/5790_2.png) [@npc1054657282](https://ziggit.dev/u/npc1054657282)\
**Post date:** [September 7, 2026, 10:24am UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/2 "2026-09-07T10:24:23Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![gwenzek](https://ziggit.dev/user_avatar/ziggit.dev/gwenzek/32/8137_2.png) [@gwenzek](https://ziggit.dev/u/gwenzek)\
**Post date:** [September 7, 2026, 11:45am UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/3 "2026-09-07T11:45:39Z")

</div>

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`

FWIW here is what I ended up doing [zml/zml/slice.zig at 053577d82d702225499d4717b25af3c584608cce · zml/zml · GitHub](https://github.com/zml/zml/blob/053577d82d702225499d4717b25af3c584608cce/zml/slice.zig#L136)

---

<div class="post-metadata">

**Author:** ![npc1054657282](https://ziggit.dev/user_avatar/ziggit.dev/npc1054657282/32/5790_2.png) [@npc1054657282](https://ziggit.dev/u/npc1054657282)\
**Post date:** [September 7, 2026, 12:31pm UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/4 "2026-09-07T12:31:20Z")

</div>

> [@gwenzek](#):
>
> 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.

Because here, `mutable` should be determined at compile time and not change at runtime, so encoding it at runtime isn’t really appropriate.

```zig
pub const slice = struct {
    pub fn Wrapper(comptime mutable: bool) type {
        return struct {
            bytes: if (mutable) []u8 else []const u8,
            shape: Shape,
            offset_bytes: usize = 0,
            byte_strides: stdx.BoundedArray(i64, constants.MAX_RANK),
            pub fn data(self: @This()) if (mutable) []u8 else []const u8 {
                return self.bytes;
            }
        };
    }
    pub fn initWrapper(shape: Shape, bytes: anytype) Wrapper(!@typeInfo(@typeOf(bytes)).pointer.is_const) {
        return .{
            .bytes = bytes,
            .shape = shape,
            .offset_bytes = 0,
            .byte_strides = shape.computeByteStrides(),
        };
    }
    ...
};

```

---

<div class="post-metadata">

**Author:** ![gwenzek](https://ziggit.dev/user_avatar/ziggit.dev/gwenzek/32/8137_2.png) [@gwenzek](https://ziggit.dev/u/gwenzek)\
**Post date:** [September 7, 2026, 12:34pm UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/5 "2026-09-07T12:34:40Z")

</div>

I get it but it makes all API really awkward because of the absence of conversion between const/mut variant

---

<div class="post-metadata">

**Author:** ![alanza](https://ziggit.dev/user_avatar/ziggit.dev/alanza/32/6006_2.png) [@alanza](https://ziggit.dev/u/alanza)\
**Post date:** [September 7, 2026, 1:16pm UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/6 "2026-09-07T13:16:15Z")

</div>

I know that this is just an example, but the correct answer here is don’t use a function when a field access suffices.

---

<div class="post-metadata">

**Author:** ![chadwain](https://ziggit.dev/user_avatar/ziggit.dev/chadwain/32/6765_2.png) [@chadwain](https://ziggit.dev/u/chadwain)\
**Post date:** [September 7, 2026, 4:24pm UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/7 "2026-09-07T16:24:30Z")

</div>

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 `@constCast` _at 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.

---

<div class="post-metadata">

**Author:** ![ericlang](https://ziggit.dev/user_avatar/ziggit.dev/ericlang/32/8515_2.png) [@ericlang](https://ziggit.dev/u/ericlang)\
**Post date:** [September 7, 2026, 5:03pm UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/8 "2026-09-07T17:03:54Z")

</div>

I am going to check on this one… This seems the most logical to me.

---

<div class="post-metadata">

**Author:** ![gwenzek](https://ziggit.dev/user_avatar/ziggit.dev/gwenzek/32/8137_2.png) [@gwenzek](https://ziggit.dev/u/gwenzek)\
**Post date:** [September 7, 2026, 6:32pm UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/9 "2026-09-07T18:32:58Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![VoilaNeighbor](https://ziggit.dev/user_avatar/ziggit.dev/voilaneighbor/32/745_2.png) [@VoilaNeighbor](https://ziggit.dev/u/VoilaNeighbor)\
**Post date:** [September 8, 2026, 12:24am UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/10 "2026-09-08T00:24:43Z")

</div>

I recall that in stdlib they are doing some sort of dependent types on `Slice`.

If Slice is const then result is const, sort of that

---

<div class="post-metadata">

**Author:** ![gwenzek](https://ziggit.dev/user_avatar/ziggit.dev/gwenzek/32/8137_2.png) [@gwenzek](https://ziggit.dev/u/gwenzek)\
**Post date:** [September 9, 2026, 5:56am UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/11 "2026-09-09T05:56:08Z")

</div>

Stolen from stdlib: [zml/stdx/bounded\_array.zig at afb3559f7fd8ca4907ae5c9c37f03d326767c51b · zml/zml · GitHub](https://github.com/zml/zml/blob/afb3559f7fd8ca4907ae5c9c37f03d326767c51b/stdx/bounded_array.zig#L59)

(it has been removed from it)

---

<div class="post-metadata">

**Author:** ![ericlang](https://ziggit.dev/user_avatar/ziggit.dev/ericlang/32/8515_2.png) [@ericlang](https://ziggit.dev/u/ericlang)\
**Post date:** [September 9, 2026, 10:16am UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/12 "2026-09-09T10:16:39Z")

</div>

True. I saw that one. It’s ugly because it uses anytype.

---

<div class="post-metadata">

**Author:** ![pasta](https://ziggit.dev/user_avatar/ziggit.dev/pasta/32/6273_2.png) [@pasta](https://ziggit.dev/u/pasta)\
**Post date:** [September 9, 2026, 1:00pm UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/13 "2026-09-09T13:00:23Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![resonancel](https://ziggit.dev/letter_avatar_proxy/v4/letter/r/db5fbb/32.png) [@resonancel](https://ziggit.dev/u/resonancel)\
**Post date:** [September 15, 2026, 11:08am UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/14 "2026-09-15T11:08:20Z")

</div>

`self: anytype` is also the only way to make your method receiver alignment-generic besides constness-generic.

---

<div class="post-metadata">

**Author:** ![pierrelgol](https://ziggit.dev/user_avatar/ziggit.dev/pierrelgol/32/10233_2.png) [@pierrelgol](https://ziggit.dev/u/pierrelgol)\
**Post date:** [September 15, 2026, 9:13pm UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/15 "2026-09-15T21:13:41Z")

</div>

in a few project I’ve used this

```zig
fn IsConstPtr(comptime T: type) bool {
    return @typeInfo(T).pointer.is_const;
}

fn ConstIf(comptime is_const: bool, comptime T: type) type {
    return if (is_const) const T else T;
}

```

and then you can have :

```zig
pub fn getLineslice(self : anytype, y: u32) []ConstIf(IsConstPtr(@TypefInfo(self)),Pixel) {
    const offset : u32 = self.width * y;
    return &self.pixels[offset + self.width];
}

```

and then at the call site it’s just:

```zig
var image: Image = undefined;

const a: []Pixel = image.getLineSclice(0);

const const_image: *const Image = &image;
const b: []const Pixel = const_image.getLineSlice(0);

```

---

<div class="post-metadata">

**Author:** ![ericlang](https://ziggit.dev/user_avatar/ziggit.dev/ericlang/32/8515_2.png) [@ericlang](https://ziggit.dev/u/ericlang)\
**Post date:** [September 15, 2026, 10:14pm UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/16 "2026-09-15T22:14:53Z")

</div>

Thanks. That is about the best trick possible, I believe.  
But it becomes kinda unreadable / tricked in my view. I stick with this simplicity.

```zig
pub fn get_line(self: *const Image) []const Pixel {
}
pub fn get_line_mut(self: *Image) []Pixel {
}

```

---

<div class="post-metadata">

**Author:** ![pierrelgol](https://ziggit.dev/user_avatar/ziggit.dev/pierrelgol/32/10233_2.png) [@pierrelgol](https://ziggit.dev/u/pierrelgol)\
**Post date:** [September 15, 2026, 10:50pm UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/17 "2026-09-15T22:50:59Z")

</div>

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`

---

<div class="post-metadata">

**Author:** ![ericlang](https://ziggit.dev/user_avatar/ziggit.dev/ericlang/32/8515_2.png) [@ericlang](https://ziggit.dev/u/ericlang)\
**Post date:** [September 26, 2026, 8:25am UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/18 "2026-09-26T08:25:32Z")

</div>

I noticed that the abandoned `bounded_array` std solution also confuses ZLS. It does not know the output type when looping through the slice.

```zig
        /// View the internal array as a slice whose size was previously set.
        pub fn slice(self: anytype) switch (@TypeOf(&self.buffer)) {
            *align(alignment.toByteUnits()) [buffer_capacity]T => []align(alignment.toByteUnits()) T,
            *align(alignment.toByteUnits()) const [buffer_capacity]T => []align(alignment.toByteUnits()) const T,
            else => unreachable,
        } {
            return self.buffer[0..self.len];
        }

```

Still I still think it is an ugly hack and feels like a missing feature in the language.

Actually the first real missing feature I encountered up until now.  
This should be read as a compliment 🙂

Are there more places in std where this is done?  
Don’t other programmers run into this “problem”?

---

<div class="post-metadata">

**Author:** ![Zonion](https://ziggit.dev/user_avatar/ziggit.dev/zonion/32/4417_2.png) [@Zonion](https://ziggit.dev/u/Zonion)\
**Post date:** [September 28, 2026, 7:58am UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/19 "2026-09-28T07:58:10Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![ericlang](https://ziggit.dev/user_avatar/ziggit.dev/ericlang/32/8515_2.png) [@ericlang](https://ziggit.dev/u/ericlang)\
**Post date:** [September 28, 2026, 8:02am UTC](https://ziggit.dev/t/avoiding-duplication-of-code-for-readonly-or-mutable-access/17519/20 "2026-09-28T08:02:50Z")

</div>

I ended up doing the same for clarity.
