Trying to grasp staged functions in Julia 0.4, I found the new documentation <https://github.com/JuliaLang/julia/pull/10673> and this issue <https://github.com/JuliaLang/julia/pull/7474> very helpful. (Note from the issue that the syntax may still change from `stagedfunction` to, perhaps, `@generated function`).
There are tons of introductory examples of how to do compile-time factorials in languages with metaprogramming and I was wondering how to do this in Julia. I've learned by doing this and my best attempt so far is (using another 0.4 feature with Val{T}) : stagedfunction fac{N}(::Type{Val{N}}) N == 1 ? z = 1 : z = N*fac(Val{N-1}); println(z); :($z) end I did not see a way to get rid of the argument in the function above, since Julia does not allow the definition of fac{N}() without N being used in the signature, so the result looks a bit awkward. I also failed to achieve the same result using macros, as it seems macros can't be recursive, but maybe I just missed it (and I wanted to use stagedfunctions anyway). Any better ideas? The println in the example is helpful to see what is actually happening: julia> fac(Val{4}) 1 2 6 24 24 julia> fac(Val{7}) 120 720 5040 5040 julia> fac(Val{7}) 5040 julia> @code_native fac(Val{6}) .text Filename: no file Source line: 0 pushq %rbp movq %rsp, %rbp movl $720, %eax # imm = 0x2D0 Source line: 0 popq %rbp ret The cool thing here is that the function works as if Julia automagically caches the previous result. The first computation of 7! just continues where 4! left off and the next computation is instant, as the instructions for Val{6} also show. Can staged functions be used (or abused) to cache one-time computational results during a session? A simpler alternative I was hoping for is the following: fac{N}(::Type{Val{N}}) = N*fac(Val{N-1}) fac(::Val{1}) = 1 but in this case the compiler does not seem to inline the result of, say, fac(Val{3}) in functions that use it.