I tried to challenge this (to some extent) with a bit of syntax gymnastics
:
const std = @import("std");
pub fn dispatch(comptime name: []const u8, args: anytype) void {
_ = args;
comptime var is_foo: bool = undefined;
comptime var is_test: bool = undefined;
comptime var suffix: i32 = undefined;
comptime success: {
is_foo = std.mem.startsWith(u8, name, "foo");
if (is_foo) {
suffix = std.fmt.parseInt(i32, name[3..], 0) catch {
@compileError("Tried to call unknown function");
};
if (suffix < 0 or suffix >= 10000) {
@compileError("Tried to call unknown function");
}
break :success;
}
is_test = std.mem.startsWith(u8, name, "test");
if (is_test) {
suffix = std.fmt.parseInt(i32, name[4..], 0) catch {
@compileError("Tried to call unknown function");
};
if (suffix < 0 or suffix >= 100) {
@compileError("Tried to call unknown function");
}
break :success;
}
@compileError("Tried to call unknown function");
}
if (is_foo) {
std.debug.print(
"Called foo function with suffix {}.\n",
.{suffix},
);
} else if (is_test) {
std.debug.print(
"Called testing function with suffix {}.\n",
.{suffix},
);
} else unreachable;
}
pub fn main() void {
dispatch("foo12", .{});
dispatch("test12", .{});
dispatch("foo3745", .{});
//dispatch("test3745", .{}); // try to uncomment me
}
This generates effectively 10100 possible âfunctionsâ (not really functions, but things you can call with dispatch("some_function_name", .{})):
foo0 to foo9999
test0 to test99
(plus equivalents with leading zeros)
Output:
Called foo function with suffix 12.
Called testing function with suffix 12.
Called foo function with suffix 3745.
Uncommenting the last line then results, expectedly, in:
comptimefunc.zig:25:17: error: Tried to call unknown function
@compileError("Tried to call unknown function");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
main: comptimefunc.zig:48:13
callMain [inlined]: /home/jbe/lib/zig/std/start.zig:666:22
callMainWithArgs [inlined]: /home/jbe/lib/zig/std/start.zig:635:20
main: /home/jbe/lib/zig/std/start.zig:650:28
1 reference(s) hidden; use '-freference-trace=5' to see all references
Thus reporting a compile-time error, demonstrating that dispatching is indeed done at compile time, right?
Not sure if this is useful for anything.