I was reading GitHub issues as a way to unwind, and I came across issue #17198 in the Zig repository. I read through the entire discussion, and after some reflection on the type system (pun intended), I thought of an idea that might serve as a reasonable middle ground. However, since I’m still relatively new to Zig, I hesitated to comment directly on the issue for fear of proposing something naive or irrelevant. At the same time, I’d like to discuss my idea on anytype
and gather feedback.
I have mixed feelings about anytype
. I don’t think it’s inherently great or terrible. I understand its purpose. While anytype
can sometimes be frustrating to work with, the ability to jump to the definition and inspect the code often makes it a manageable annoyance. Based on the issue’s discussion, the primary complaint seems to be that anytype
shifts the responsibility of understanding the expected type to the user of the code. Although this can be mitigated with compile-time checks in userland, it does require extra work from the implementer. The result is that users can be left with something quite opaque.
This led me to an idea. Since the maintainers prefer to avoid low-quality proposals (which I understand and respect), I won’t submit this formally. I’m content with the current state of things, but I still wanted to share the thought, and who knows maybe I’m totally wrong and this can’t work at all, or maybe someone can make an actual good proposal based on that idea.
Basically instead of allowing anytype
to be used directly in function definitions, what if anytype
could only be accessed through a new builtin, like @anytype(fn (type) bool)
? This function would take another function that accepts a type and returns a bool
.
fn isNumeric(comptime T: type) bool {
return switch (@typeInfo(T)) {
.Float, .Int => true,
else => @compileError("The type provided " ++ @typeName(T) ++ " isn't numeric"),
};
}
fn add(value: @anytype(isNumeric)) @TypeOf(value) {
return value + value;
}
pub fn main() !void {
const i: i32 = 4;
std.debug.print("{d}", .{add(i)});
}
I realize this explanation might be a bit unclear, but the core idea is that in order to use anytype
in an API, the developer would be required to provide a function that “validates” or “processes” the type. This would enforce a layer of explicit type handling, potentially reducing the ambiguity that anytype
can introduce.
Does this make sense as a possible approach? I’d love to hear thoughts on whether this could address some of the concerns raised in the issue.