# No more evaluation in closed module in Julia 1.5+ == no more code-gen in modules?

**URL:** https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804
**Category:** General Usage
**Created:** [December 14, 2020, 3:21pm UTC](https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804 "2020-12-14T15:21:08Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![asprionj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asprionj/32/6856_2.png) [@asprionj](https://discourse.julialang.org/u/asprionj)
#### Post date: [December 14, 2020, 3:21pm UTC](https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804/1 "2020-12-14T15:21:08Z")

</div>

In some “helper package” (module) I have some functions similar to that one:

```julia
function make_polynomial(c::Array{T,1} where T<:Number; return_code=false)
    if length(c) == 1
        f_body = :($(c[1]))
    else
        f_body = :($(c[end]))
        for ci in reverse(c[1:end-1])
            f_body = :($ci + x*$f_body)
        end
    end
    f_code = :(x -> $f_body)

    return return_code ? f_code : eval(f_code)
end

```

This one generates the code for a function efficiently evaluating a 1D-polynomial by Horner’s rule, for a given value of the independent variable. It then either returns the code defining this function, or directly this function (via an `eval`).

Now, since Julia 1.5, another module, utilising this helper module, does not precompile anymore. (Due to the fact that the `eval` happens in the closed helper module, “breaking incremental precompilation”, “don’t do this”.)

Any suggestion on what I should do here? Is there any other way of getting a function calculating something from a runtime-valued variable (`x`), by using hard-coded (and “efficiently unrolled”) coefficient values from a vector of such coefficients?

And no, I cannot change all the callers to get the code and `eval` it there; would take me days…

---

<div class="post-metadata">

### Author: ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)
#### Post date: [December 14, 2020, 3:26pm UTC](https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804/2 "2020-12-14T15:26:39Z")

</div>

Can you build the anonymous function directly with code instead using expressions?

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [December 14, 2020, 3:27pm UTC](https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804/3 "2020-12-14T15:27:00Z")

</div>

you should check out `evalpoly`. It does what you want I think.

---

<div class="post-metadata">

### Author: ![asprionj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asprionj/32/6856_2.png) [@asprionj](https://discourse.julialang.org/u/asprionj)
#### Post date: [December 14, 2020, 3:34pm UTC](https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804/4 "2020-12-14T15:34:34Z")

</div>

Thanks, but the evaluation of a polynomial is just one example of several similar functions.  
(BTW, this also takes around 38 ns on my PC, compared to 26 ns of the above “pre-generated” solution.)

---

<div class="post-metadata">

### Author: ![asprionj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asprionj/32/6856_2.png) [@asprionj](https://discourse.julialang.org/u/asprionj)
#### Post date: [December 14, 2020, 3:41pm UTC](https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804/5 "2020-12-14T15:41:32Z")

</div>

That’s what I tried in several ways, but could not come up with a solution. I mean, of course it is possible, but not with the same performance. The goal is to fully utilise the fact that, at construction of the function, the number of coefficients and their values are known, so no loop is needed. With the above implementation, using `c = randn(5)`, `@code_typed` gives:

```julia
CodeInfo(
1 ─ %1 = Base.mul_float(x, -0.12695133782437318)::Float64
│ %2 = Base.add_float(0.21835680782713537, %1)::Float64
│ %3 = Base.mul_float(x, %2)::Float64
│ %4 = Base.add_float(1.0391119724087707, %3)::Float64
│ %5 = Base.mul_float(x, %4)::Float64
│ %6 = Base.add_float(-0.7659185523381208, %5)::Float64
│ %7 = Base.mul_float(x, %6)::Float64
│ %8 = Base.add_float(0.8006651451155793, %7)::Float64
└── return %8
) => Float64

```

Anything involving a vector (or tuple), and some sort of loop, results in quite some overhead and around 42 instead of 26 ns execution time (evaluated using `@benchmark`).

Is there a way of accessing the value of a Symbol (or Expression), in the caller scope, inside a macro?

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [December 14, 2020, 3:46pm UTC](https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804/6 "2020-12-14T15:46:27Z")

</div>

> [@asprionj](#):
>
> `($ci + x*$f_body)`

The problem is that the above isn’t allowing fused multiply add to be used. You probably want `(muladd(x, $f_body, $ci))`.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [December 14, 2020, 3:48pm UTC](https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804/7 "2020-12-14T15:48:16Z")

</div>

Use a generated function, pass in the length as a `Val{n}` value? Alternatively, disable pre-compilation: ` __precompile__ (false)`.

---

<div class="post-metadata">

### Author: ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)
#### Post date: [December 14, 2020, 3:52pm UTC](https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804/8 "2020-12-14T15:52:02Z")

</div>

Thanks for the explanation.

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [December 14, 2020, 4:16pm UTC](https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804/9 "2020-12-14T16:16:21Z")

</div>

You can also pass in the calling scope’s eval function and use that instead of the module eval.

---

<div class="post-metadata">

### Author: ![asprionj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asprionj/32/6856_2.png) [@asprionj](https://discourse.julialang.org/u/asprionj)
#### Post date: [December 14, 2020, 4:16pm UTC](https://discourse.julialang.org/t/no-more-evaluation-in-closed-module-in-julia-1-5-no-more-code-gen-in-modules/51804/10 "2020-12-14T16:16:29Z")

</div>

Hehe, thanks. Brings down the operations to:

```julia
CodeInfo(
1 ─ %1 = Base.muladd_float(x, -0.12695133782437318, 0.21835680782713537)::Float64
│ %2 = Base.muladd_float(x, %1, 1.0391119724087707)::Float64
│ %3 = Base.muladd_float(x, %2, -0.7659185523381208)::Float64
│ %4 = Base.muladd_float(x, %3, 0.8006651451155793)::Float64
└── return %4
) => Float64

```

However, in the exec. time, I can hardly see any difference…
