# How to avoid compilation of an uncalled function

**URL:** <https://discourse.julialang.org/t/how-to-avoid-compilation-of-an-uncalled-function/100058>\
**Category:** General Usage\
**Tags:** compilation, precompilation, lazy-evaluation\
**Created:** [June 8, 2023, 3:55pm UTC](https://discourse.julialang.org/t/how-to-avoid-compilation-of-an-uncalled-function/100058 "2023-06-08T15:55:21Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)\
**Post date:** [June 8, 2023, 3:55pm UTC](https://discourse.julialang.org/t/how-to-avoid-compilation-of-an-uncalled-function/100058/1 "2023-06-08T15:55:21Z")

</div>

I have some code that generates a lot of function calls within different code branches. Each function call generates a different function instance. All these function instances are getting precompiled when my module is precompiled, which is killing the precompilation time. The thing is, even though many functions are instantiated (i.e. a call exists in the code), very few of them will actually get called. I would like to ensure that certain functions are only compiled when they are actually called, and not when they are instantiated. Is this possible?

Here is a MWE of the problem:

```julia
function valuedispatch_expr(::Val{lower}, ::Val{upper}, val, fun) where {lower, upper}
    if lower >= upper
        return :( $fun(Val($upper)) ) 
    end
    midpoint = lower + div(upper - lower, 2)
    expr_a = valuedispatch_expr(Val(lower), Val(midpoint), val, fun)
    expr_b = valuedispatch_expr(Val(midpoint+1), Val(upper), val, fun)
    return quote
        if $val <= $midpoint
            $expr_a
        else
            $expr_b
        end
    end
end

macro valuedispatch_macro(lower::Int, upper::Int, val, fun)
    ex = valuedispatch_expr(Val(lower), Val(upper), esc(val), esc(fun))
    quote
        $ex
        return nothing
    end
end

@eval valuedispatch_1_32(val, fun) = @valuedispatch_macro(1, 32, val, fun)

@generated function myfun(::Val{v}) where v
    println("Compiling ", v)
    return :(println("Running ", $v))
end

println(valuedispatch_1_32(3, myfun))

```

While only one function actually gets called, 32 get compiled.

EDIT: At first I thought this might be because the compiler wants to understand the output type, so needs to compile all functions for that reason. However, I’ve now changed the code so that the `valuedispatch` function always returns `nothing`. The problem still persists.

---

<div class="post-metadata">

**Author:** ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)\
**Post date:** [June 8, 2023, 5:39pm UTC](https://discourse.julialang.org/t/how-to-avoid-compilation-of-an-uncalled-function/100058/2 "2023-06-08T17:39:47Z")

</div>

You can use the `@nospecialize` macro at the beginning of the generated function, as follows:

```julia
macro valuedispatch_macro(lower::Int, upper::Int, val, fun)
    ex = valuedispatch_expr(Val(lower), Val(upper), esc(val), esc(fun))
    return quote
        @nospecialize
        $ex
        return nothing
    end
end

```

Because `valuedispatch_1_32` is now a generic function, it knows nothing about the function `myfun` being passed in, and so cannot precompile it.

---

<div class="post-metadata">

**Author:** ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)\
**Post date:** [June 8, 2023, 8:54pm UTC](https://discourse.julialang.org/t/how-to-avoid-compilation-of-an-uncalled-function/100058/3 "2023-06-08T20:54:55Z")

</div>

I have [a similar problem](https://discourse.julialang.org/t/how-to-avoid-compilation-of-an-uncalled-function-inside-a-generated-function/100072), but in a `@generated` function. I haven’t, as yet, been able to fix it.
