# Precompile() @generated functions

**URL:** <https://discourse.julialang.org/t/precompile-generated-functions/1240>\
**Category:** General Usage\
**Created:** [January 1, 2017, 8:54pm UTC](https://discourse.julialang.org/t/precompile-generated-functions/1240 "2017-01-01T20:54:32Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![smldis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/smldis/32/1735_2.png) [@smldis](https://discourse.julialang.org/u/smldis)\
**Post date:** [January 1, 2017, 8:54pm UTC](https://discourse.julialang.org/t/precompile-generated-functions/1240/1 "2017-01-01T20:54:32Z")

</div>

Hello,

I am writing the initialization part of my julia program and I want to define functions that depend on parameters already defined.

I am using @generated for the definition of the function.  
Then I have to use precompile() for making the solve thing happening at this stage:

```julia
@generated function my_fun(x)
        computed_results = solve(BIG_PROBLEM) 
    return :($computed_results[x])
end
precompile(my_fun,(Int64,)) 

```

Is there another way to do this?  
Why precompile needs the type tuple also if I annotate the arguments?  
Why I need to provide the type tuple to precompile also if `x` is not used in the expression interpolation?

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [January 1, 2017, 9:39pm UTC](https://discourse.julialang.org/t/precompile-generated-functions/1240/2 "2017-01-01T21:39:08Z")

</div>

If the results of `solve` is serializalbe, this in global scope should work:

```julia
const computed_results = solve(BIG_PROBLEM) 

```

Also, I started incorporating static computations like this into the `deps/build.jl` file. This way, the user can rebuild things more transparently and not just over deleting some precompiled cache file (which might as well be independent of the computation).

> Why precompile needs the type tuple also if I annotate the arguments?

Because precompilation is mostly about lowering and typeinference. I guess one could introduce more heuristics to figure out the types e.g. by your typed arguments. But you still would need to select the method, if a function combines multiple signatures 😉  
I’m sure that these things will get a lot more comfortable in the future, until then, it’s probably a lot more consistent to always force the user to supply the type tuple.

---

<div class="post-metadata">

**Author:** ![smldis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/smldis/32/1735_2.png) [@smldis](https://discourse.julialang.org/u/smldis)\
**Post date:** [January 1, 2017, 10:08pm UTC](https://discourse.julialang.org/t/precompile-generated-functions/1240/3 "2017-01-01T22:08:33Z")

</div>

Thank you for replying. It does make sense.  
I don’t like the global const solution because the code readability is affected by the fact the user will not be able to understand that the computation is used only for generating the function. Another problem in general is that the body could depend on type of x.

What about the following solution?  
I could define a new macro called `@generated_precompile` that could embed the precompile call and also derive the type of the arguments for the generated function and precompile by analizing the argument given.

Is this considered useful?  
Can I open an issue with a request for this?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [January 2, 2017, 12:34am UTC](https://discourse.julialang.org/t/precompile-generated-functions/1240/4 "2017-01-02T00:34:15Z")

</div>

What you are allowed to do in a `@generated` function is very limited. Something like ` computed_results = solve(BIG_PROBLEM)` inside a `@genrated` function is not the right way to do it. The results should be cached in a dict or something. You can generate the function from the result with an `@eval`. `@generated` functions are meant for non trivial computations with type parameters which you seem to not do at all.

For limitations of what you are allowed to do, see [http://docs.julialang.org/en/latest/manual/metaprogramming.html#Generated-functions-1](http://docs.julialang.org/en/latest/manual/metaprogramming.html#Generated-functions-1).

Specifically (quoting from the manual), you are among other things not allowed to.

- Caching of native pointers.

- Interacting with the contents or methods of Core.Inference in any way.

- Observing any mutable state.

- Inference on the generated function may be run at any time, including while your code is attempting to observe or mutate this state.

- Taking any locks: C code you call out to may use locks internally, (for example, it is not problematic to call malloc, even though most implementations require locks internally) but don’t attempt to hold or acquire any while executing Julia code.

- Calling any function that is defined after the body of the generated function. This condition is relaxed for incrementally-loaded precompiled modules to allow calling any function in the module.

I would strongly recommend reconsidering using `@generated` functions for this use case.
