Point 2 is not really true for Zig, functions don't need to be specially marked to be callable at compile time. The comptime keyword is sometimes required to force compile time resolution (Zig currently doesn't eagerly try to resolve function calls at compile time), but in any compile-time-only context not even that is necessary, like so:
fn double(n: usize) usize {
return 2*n;
}
const MyArrType = [double(5)]u8;
Similarly, point 3 is not really true either, what matters in Zig as well is the path that the function took during evaluation.
const std = @import("std");
fn double(n: usize) usize {
if (n % 2 == 0) {
std.debug.print("even!", .{});
}
return 2*n;
}
const MyArrayType = [double(5)]u8; // this works
//const Bad = [double(6)]u8; // this will fail to compile
You are right about allocation not working during comptime evaluation at the moment, but this is not a final design decision, just the current status quo.