Question: Why can’t I use a function call as a switch prong in Zig, but direct range checks work?
Hi everyone,
I’m running into an issue with a switch statement in my Zig code, and I’m hoping someone can explain what’s going on
I have a simple function to check if a byte is alphabetic same when using std.ascii.isAlphabetic
Why is this happening? Is it because switch prongs need to be comptime-known values, and calling a function like isAlphabetic(chr) isn’t considered comptime even though the function itself uses comptime ranges? Does the documentation mention this requirement for switch statements? I’d love to understand the reasoning behind why the function call doesn’t work but the direct usage does.
There’s several issues: first, yeah, isAlphabetic() can’t be comptime because it has a runtime paramter, even though it ‘statically evaluates’ this runtime parameter. The other issue though is that your isAlphabetic() function returns a boolean, while the switch works on u8 values.
A switch is not a replacement for a dynamic if-else cascade, think of it more like a static jump table which you populate at comptime via the prong-values - and a function that returns a boolean doesn’t really work with the jump table idea even if it can be evaluated at comptime, it would need to return a “jump table index” instead of a true/false value - and I think in that case you’d also need to use an ‘inline prong’ so that Zig ‘unrolls’ the comptime function call into all resulting prongs…
PS: …one interesting question would be if a non-comptime inline function should be accepted in a switch-prong… since inline in Zig hoists the function body into the caller - e.g. more like a C macro, and the compiler should then be able to figure out if the hoisted code can be evaluated at comptime even without being explicitely marked as comptime…
I think the improvement to readability justifies having such a feature. We can today handle the use cases with inline for, but the semantic is poor. Using a fake loop to emulate a switch is just not a nice way of doing things.
Safe bet that for the more complex cases, emulating it with inline for simply won’t give the compiler what it needs to generate efficient code. There’s been some movement on that issue, so here’s hoping.