I think Zig really shines here: https://ziglang.org/documentation/master/#comptime
A key difference is that in this C# package, `[Comptime]` is an attribute (annotation? not sure on the C# term) applied to methods. In Zig, the `comptime` keyword can be applied to pretty much any expression. In the C# package, if you want to do factorial at runtime and at compile time, (I think, from reading the README) you need to define the same function twice, one with `[Comptime]` and once without. Contrast this to Zig, where if you have a regular runtime factorial function, you can just execute it at compile time like:
const x = comptime factorial(n);
Another limitation of the C# package is it only works with primitive types and collections. Zig comptime works on any arbitrary types.There's also Nim, it shines even more in compile time and has proper compile time macros :)
D was already doing it in 2010 thereabouts, an then there is the whole reader macros in Lisp and Scheme.