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.

Reply via email to