# Use of eval in closed module and "incremental compilation may be broken"

**URL:** <https://discourse.julialang.org/t/use-of-eval-in-closed-module-and-incremental-compilation-may-be-broken/30028>\
**Category:** General Usage\
**Created:** [October 17, 2019, 3:01pm UTC](https://discourse.julialang.org/t/use-of-eval-in-closed-module-and-incremental-compilation-may-be-broken/30028 "2019-10-17T15:01:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [October 17, 2019, 3:01pm UTC](https://discourse.julialang.org/t/use-of-eval-in-closed-module-and-incremental-compilation-may-be-broken/30028/1 "2019-10-17T15:01:05Z")

</div>

In Package A we would like to offer facilities to write metadata about models of a specific type that would be written in other packages, say B.

To do this we have something like this

In Package A:

```julia
module A
input_type(T) = nothing
function meta(T, input_type)
  ex = quote
    input_type(::Type{<:$T}) = $input_type
  end
  eval(ex)
end
end

```

in Package B:

```julia
module B
import A: meta
export NewModel
struct NewModel end
meta(NewModel, Real)
end

```

The expected output being that

```julia-repl
julia> using A, B
julia> input_type(B)
Real

```

(Incidentally if you do this in the REPL replacing `import A` with `import Main.A` it seems to work fine).

However in my context `A` and `B` are two separate packages and doing the steps above can lead to the following warning when precompiling `B`:

```julia
using B
[Info: Precompiling B [...]
WARNING: eval into closed module A:
Expr(:block, #= Symbol( ...

```

resulting in a warning `incremental compilation may be broken for this module`. I suspect this is due to a poor use of `eval` and issues with where/when things are evaluated but it’s unclear to me how to fix the issue.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [October 17, 2019, 3:38pm UTC](https://discourse.julialang.org/t/use-of-eval-in-closed-module-and-incremental-compilation-may-be-broken/30028/2 "2019-10-17T15:38:54Z")

</div>

There’s no need to use `eval()` here: Julia’s normal method dispatch already handles this situation perfectly:

```julia
julia> module A
         export input_type
         
         input_type(T) = nothing
       end
WARNING: replacing module A.
Main.A

julia> module B
         import ..A: input_type
         export NewModel
         
         struct NewModel end
         input_type(::Type{NewModel}) = Real
       end
WARNING: replacing module B.
Main.B

julia> A.input_type(B.NewModel)
Real

```

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [October 17, 2019, 3:43pm UTC](https://discourse.julialang.org/t/use-of-eval-in-closed-module-and-incremental-compilation-may-be-broken/30028/3 "2019-10-17T15:43:45Z")

</div>

Yes I’m aware this could be accomplished by multiple dispatch and I apologise that my example is a bit too simplistic and encourages this answer.

Let’s say I really want to use `eval` here because I don’t want to call `input_type` in `module B` (effectively there’s a series of such functions from `A` that I want to be wrapped in that function `meta` to reduce code duplication when possible).

Maybe to clarify, I’d like `A` to expose a function `meta` that can assign a number of traits, something like

```julia
function meta(T, ....)
  trait_function1(T, ...)
  trait_function2(T, ...)
end

```

If I do this without quote I get other errors like “static parameters cannot be used in closure” so this is why I went for `eval`.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [October 17, 2019, 3:53pm UTC](https://discourse.julialang.org/t/use-of-eval-in-closed-module-and-incremental-compilation-may-be-broken/30028/4 "2019-10-17T15:53:25Z")

</div>

I’m still pretty sure `eval()` is the wrong tool here. What about a macro that expands to the code you actually want to generate? This seems like a perfect use-case for a macro.

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [October 17, 2019, 3:56pm UTC](https://discourse.julialang.org/t/use-of-eval-in-closed-module-and-incremental-compilation-may-be-broken/30028/5 "2019-10-17T15:56:27Z")

</div>

Yeah I guess I should try with a macro, I’ll report here if I manage to get that working, thanks. (and I agree that eval is likely not the best tool).

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [October 18, 2019, 5:09pm UTC](https://discourse.julialang.org/t/use-of-eval-in-closed-module-and-incremental-compilation-may-be-broken/30028/6 "2019-10-18T17:09:44Z")

</div>

So if anyone should read this question in the future, I finally found out that the problem was to specify properly where the `eval` happens (and yes you actually have to use `eval` here because the emitted code has to be from A not B)

Anyway so calling `parentmodule(T).eval` solves the problem, it took me some time to find it but it works perfectly for my use case 😅
