# Using struct created at runtime as argument type

**URL:** <https://discourse.julialang.org/t/using-struct-created-at-runtime-as-argument-type/21983>\
**Category:** General Usage\
**Tags:** question\
**Created:** [March 18, 2019, 2:12am UTC](https://discourse.julialang.org/t/using-struct-created-at-runtime-as-argument-type/21983 "2019-03-18T02:12:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![adriaan](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@adriaan](https://discourse.julialang.org/u/adriaan)\
**Post date:** [March 18, 2019, 2:12am UTC](https://discourse.julialang.org/t/using-struct-created-at-runtime-as-argument-type/21983/1 "2019-03-18T02:12:45Z")

</div>

For a project I’m currently working on I have to do a lot of code generation. I run into a problem when I tried to create structs at runtime and use them in method definitions as argument types. It would be great if someone knows some kind of workaround for this problem or has an explanation for this behaviour. I created a minimal example to illustrate the problem.

main

```julia
push!(LOAD_PATH, @ __DIR__ )

using A

Core.eval(A, :(struct Foo end))

# B should be evaluated after A was modified
using B

```

A.jl

```julia
module A end

```

B.jl

```julia
module B
  using A
  function func1(value::A.Foo) end
end

```

Error message

```julia
ERROR: LoadError: UndefVarError: Foo not defined
Stacktrace:
 [1] getproperty(::Module, ::Symbol) at ./sysimg.jl:13
 [2] top-level scope at none:0
 [3] include at ./boot.jl:326 [inlined]
 [4] include_relative(::Module, ::String) at ./loading.jl:1038
 [5] include(::Module, ::String) at ./sysimg.jl:29
 [6] top-level scope at none:2
 [7] eval at ./boot.jl:328 [inlined]
 [8] eval(::Expr) at ./client.jl:404
 [9] top-level scope at ./none:3
in expression starting at /home/xxx/Documents/julia-bug-01-min-example/B.jl:3
ERROR: LoadError: Failed to precompile B [top-level] to /home/xxx/.julia/compiled/v1.1/B.ji.
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] compilecache(::Base.PkgId, ::String) at ./loading.jl:1197
 [3] _require(::Base.PkgId) at ./loading.jl:960
 [4] require(::Base.PkgId) at ./loading.jl:858
 [5] require(::Module, ::Symbol) at ./loading.jl:853
 [6] include at ./boot.jl:326 [inlined]
 [7] include_relative(::Module, ::String) at ./loading.jl:1038
 [8] include(::Module, ::String) at ./sysimg.jl:29
 [9] exec_options(::Base.JLOptions) at ./client.jl:267
 [10] _start() at ./client.jl:436
in expression starting at /home/xxx/Documents/julia-bug-01-min-example/main.jl:8

```

---

<div class="post-metadata">

**Author:** ![anon67531922](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@anon67531922](https://discourse.julialang.org/u/anon67531922)\
**Post date:** [March 18, 2019, 4:23am UTC](https://discourse.julialang.org/t/using-struct-created-at-runtime-as-argument-type/21983/2 "2019-03-18T04:23:36Z")

</div>

Hi Adriaan 👋

I imagine there could be a more “Julian” way to do what you are trying to do. You might get more valuable help if you give a little more context around what you are trying to do.

That aside, it looks like your `main` (a hint you are coming from another language 😊) is trying to create a `struct Foo` in a module `A` and your `B` is trying to dispatch on `A.Foo`, but `A.Foo` doesn’t exist when `B` is used.

I can think of two ways to proceed and there may be a better way still.

## Option 1

One way to do this would be to create an `AbstractFoo` in `A`. Then, in your `main` you can just do

```julia-auto
struct Foo <: A.AbstractFoo end

```

Then `B` can contain something like

```julia-auto
func1(value::A.AbstractFoo) = error("Must implement `func1` for YourFoo <: AbstractFoo")

```

so you would implement

```julia-auto
function func1(value::Foo)
    # do stuff with Foo
end

```

also in your `main`.

Your `main` would look like:

```julia-auto
module Main

using A,B

struct Foo <: A.AbstractFoo end

function func1(value::Foo)
    # do stuff with Foo
end

```

## Option 2

Inside `A`, you can create a method:

```julia-auto
module A

function createfoo(args...)
    # Use `eval` to generate a Foo struct 
end

```

and inside `B` you can create a method

```julia-auto
module B

function createfoofunc(args...)
    # use `eval` to generate a function to dispatch on your Foo
end

```

And then in your `main` you would do something like:

```julia-auto
module Main

using A,B

A.createfoo(args...)

B.createfoofunc(args...)

end

```

Like I said, I suspect there is a better way. If you give some more context, it might help someone give a better answer 😊

---

<div class="post-metadata">

**Author:** ![adriaan](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@adriaan](https://discourse.julialang.org/u/adriaan)\
**Post date:** [March 18, 2019, 3:01pm UTC](https://discourse.julialang.org/t/using-struct-created-at-runtime-as-argument-type/21983/3 "2019-03-18T15:01:19Z")

</div>

Hi Eric,

Thank you very much for your reply. The solutions you proposed definitely make sense to me. However I suspect that I can’t use a solution like this in my case. I guess I should have been more specific from the beginning, but to give more context now: I’m working on a plugin system for a simulation tool (written in C++), so that certain components can be developed with Julia. To provide the necessary C++ bindings I use the Julia C-API and I do something similar to the following code snippet within the initialization phase of the program.

```julia
jl_eval_string("using CppBindings");
jl_module_t* cppBindings = jl_eval_string("CppBindings");
add_methods_and_types(cppBindings);

```

Hereby CppBindings.jl is more or less an empty module and all its methods and types are generated by the C++ application. The purpose of these methods/types is apparently to wrap C++ methods/types.

When the simulation is running, specific actions can be hooked with Julia methods. This looks somehow like this:

```julia
module Plugin
  using CppBindings

  function julia_hook(arg)
    # No Problem to access generated types within method
    x = CppBindings.ArbitraryType(42)
    # No Problem to access generated methods within method
    y = CppBindings.arbitrary_method(1, 2, 3)
  end

  # For some reason using generated types in method definition doesn't work
  function another_julia_hook(arg::CppBindings.ArbitraryType) 
    ...
  end
end

```

Almost everything works as intended except that I can’t use types generated by the C++ application as argument types. Obviously being able to do this is crucial to extend functionality.

In the given scenario it’s unfortunately not possible to use your solutions because I don’t have a “main” Julia file as an entry point. Instead everything is put together by the C++ application. For reasonable modularization it’s also important that I can use these types as argument types within seperate module files.

As you already recognized I’m relatively new to Julia 😅 so I have a hard time judging whether this behaviour is to be expected or if this is some kind of bug.

---

<div class="post-metadata">

**Author:** ![anon67531922](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@anon67531922](https://discourse.julialang.org/u/anon67531922)\
**Post date:** [March 18, 2019, 3:59pm UTC](https://discourse.julialang.org/t/using-struct-created-at-runtime-as-argument-type/21983/4 "2019-03-18T15:59:26Z")

</div>

> [@adriaan](#):
>
> In the given scenario it’s unfortunately not possible to use your solutions because I don’t have a “main” Julia file as an entry point.

Ah, but you do have a `main`. It is called `Plugin` in this case 😊

I have no idea about C++ bindings, but I still think something along the lines of Option 2 could work for you.

I “think” you can write Julia methods with inputs that are driven by C++ but do the metaprogramming within Julia. It almost seems like you are trying to do Julia metaprogramming entirely from C++ 😅 I think there are only a handful or mortals that could get that to work and I am not one of them 😅

Sounds like this is over my head. Hope someone else chimes in 🙏

---

<div class="post-metadata">

**Author:** ![adriaan](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@adriaan](https://discourse.julialang.org/u/adriaan)\
**Post date:** [March 21, 2019, 10:29am UTC](https://discourse.julialang.org/t/using-struct-created-at-runtime-as-argument-type/21983/5 "2019-03-21T10:29:55Z")

</div>

> I “think” you can write Julia methods with inputs that are driven by C++ but do the metaprogramming within Julia. It almost seems like you are trying to do Julia metaprogramming entirely from C++ 😅

Yes it’s probably best practice to to encapsulate the functionality into Julia methods and call these from C++. For the most part I’m already doing that 😉

Anyway I came up with a solution to the problem. I had to deactivate precompilation in modules that depend on types generated at runtime. Otherwise an unmodified version of the module is used in the precompilation phase. The example I posted above works fine if change it this way:

```julia
__precompile__ (false)
module B
  using A
  function func1(value::A.Foo) end
end

```

In general eval shouldn’t be used on already defined modules to prevent such problems in the first place (in some cases the compiler will also show a warning). However there might be exceptions where it’s not possible to avoid it and the only solution is to deactivate precompilation for specific modules.
