# Mixin alternative using const declarations

**URL:** <https://ziggit.dev/t/mixin-alternative-using-const-declarations/6091>\
**Category:** Brainstorming\
**Tags:** language\
**Created:** [September 22, 2024, 7:22pm UTC](https://ziggit.dev/t/mixin-alternative-using-const-declarations/6091 "2024-09-22T19:22:23Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [September 22, 2024, 7:22pm UTC](https://ziggit.dev/t/mixin-alternative-using-const-declarations/6091/1 "2024-09-22T19:22:23Z")

</div>

@pierrelgol and I are working on replacing `usingnamespace` for Fluent (and just a general refactor and expansion) and tossed some ideas back and fourth.

One idea that we’re converging on is using public `const` declarations as they can be used as both class level and instance level functions:

```zig
const std = @import("std");

pub fn eq_impl(comptime T: type) type {   
    return struct {
        pub fn call(self: T, other: T) bool {
            return self.data == other.data;
        }  
    };
}

const Bar = struct {
    data: i32 = 42,
    // here's where the implementation gets "mixed-in"
    const eq = eq_impl(Bar).call;
};

pub fn main() !void {

    const x: Bar = .{ .data = 42 };
    const y: Bar = .{ .data = 42 };

    if (x.eq(y)) // instance level
        std.log.info("It worked", .{});
    
    if (Bar.eq(x, y)) // type level
        std.log.info("It worked", .{});

    return;
}

```

Here, you can see that the public `const` declaration allows us to import an implementation that can be used both as a class level and instance level function implementation. We’re pretty happy with this and will use it in its most basic form to prevent code duplication, but I’m curious how far this can go.

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [September 22, 2024, 7:25pm UTC](https://ziggit.dev/t/mixin-alternative-using-const-declarations/6091/2 "2024-09-22T19:25:37Z")

</div>

Just to note, you can extend this quite easily using `comptime` function parameters that take in your meta-functions to be specialized. The `Bar` example is highly trivial but it matches our use case for Fluent - not true in general but just for demonstration’s sake.

A little more involved would be something like so… (pseudo-code):

```zig
pub fn MyImpl(comptime Self: type) type {
    return struct {
        pub fn foo(self: Self, ...) ...
        pub fn bar(self: Self, ...) ...
    };
}

pub fn Thing(comptime T: type, comptime Impl: anytype) type {
    return struct {
        const Self = @This();     
        const foo = Impl(Self).foo;
        const bar = Impl(Self).bar;
    };
}

const Widget = Thing(u8, MyImpl);

```

The major difference is there’s no “silent-injection” as it were. You have to specifically declare `foo, bar, etc...` in the interface.
