# Function fails when used in precompile workload

**URL:** https://discourse.julialang.org/t/function-fails-when-used-in-precompile-workload/131095
**Category:** General Usage
**Tags:** question, precompilation
**Created:** [July 27, 2025, 1:25pm UTC](https://discourse.julialang.org/t/function-fails-when-used-in-precompile-workload/131095 "2025-07-27T13:25:43Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [July 27, 2025, 1:25pm UTC](https://discourse.julialang.org/t/function-fails-when-used-in-precompile-workload/131095/1 "2025-07-27T13:25:43Z")

</div>

I have the following function:

```julia-auto
function str2type(name)
    typename = Symbol(name)
    t = getfield(Main, typename)
    instance = t()
end

```

I need it to get an instance of a type of a marker struct at runtime based on strings in the setup.yaml file.

Normally this works fine, but it fails when I call it in the @setup\_workload section of my package.

Example:

```julia-auto
@setup_workload begin
    @compile_workload begin
        a = Velocity_Constant()
        b = str2type("Velocity_Constant")
    end
end

```

The assignment to `a` works fine, the assignment to `b` fails with the error:

```julia-auto
julia> using FLORIDyn
Precompiling FLORIDyn...
Info Given FLORIDyn was explicitly requested, output will be shown live 
ERROR: LoadError: UndefVarError: `Velocity_Constant` not defined in `Main`
Stacktrace:
 [1] str2type(name::String)
   @ FLORIDyn ~/repos/FLORIDyn.jl/src/FLORIDyn.jl:65
 [2] macro expansion
   @ ~/repos/FLORIDyn.jl/src/FLORIDyn.jl:249 [inlined]
 [3] macro expansion
   @ ~/.julia/packages/PrecompileTools/L8A3n/src/workloads.jl:78 [inlined]
 [4] macro expansion
   @ ~/repos/FLORIDyn.jl/src/FLORIDyn.jl:243 [inlined]
 [5] macro expansion
   @ ~/.julia/packages/PrecompileTools/L8A3n/src/workloads.jl:140 [inlined]
 [6] top-level scope
   @ ~/repos/FLORIDyn.jl/src/FLORIDyn.jl:240
 [7] include
   @ ./Base.jl:562 [inlined]
 [8] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::Nothing)
   @ Base ./loading.jl:2881
 [9] top-level scope
   @ stdin:6
in expression starting at /home/ufechner/repos/FLORIDyn.jl/src/FLORIDyn.jl:4
in expression starting at stdin:6
  ✗ FLORIDyn
  0 dependencies successfully precompiled in 4 seconds. 119 already precompiled.

ERROR: The following 1 direct dependency failed to precompile:

FLORIDyn 

Failed to precompile FLORIDyn [fc770985-7669-4833-bc54-a38444eb6027] to "/home/ufechner/.julia/compiled/v1.11/FLORIDyn/jl_h52Xz5".
ERROR: LoadError: UndefVarError: `Velocity_Constant` not defined in `Main`
Stacktrace:
 [1] str2type(name::String)
   @ FLORIDyn ~/repos/FLORIDyn.jl/src/FLORIDyn.jl:65
 [2] macro expansion
   @ ~/repos/FLORIDyn.jl/src/FLORIDyn.jl:249 [inlined]
 [3] macro expansion
   @ ~/.julia/packages/PrecompileTools/L8A3n/src/workloads.jl:78 [inlined]
 [4] macro expansion
   @ ~/repos/FLORIDyn.jl/src/FLORIDyn.jl:243 [inlined]
 [5] macro expansion
   @ ~/.julia/packages/PrecompileTools/L8A3n/src/workloads.jl:140 [inlined]
 [6] top-level scope
   @ ~/repos/FLORIDyn.jl/src/FLORIDyn.jl:240
 [7] include
   @ ./Base.jl:562 [inlined]
 [8] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::Nothing)
   @ Base ./loading.jl:2881
 [9] top-level scope
   @ stdin:6
in expression starting at /home/ufechner/repos/FLORIDyn.jl/src/FLORIDyn.jl:4
in expression starting at stdin:

```

What could be the reason?

(Full source code: [FLORIDyn.jl/src at main · ufechner7/FLORIDyn.jl · GitHub](https://github.com/ufechner7/FLORIDyn.jl/tree/main/src))

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [July 27, 2025, 4:17pm UTC](https://discourse.julialang.org/t/function-fails-when-used-in-precompile-workload/131095/2 "2025-07-27T16:17:18Z")

</div>

`Velocity_Constant` seems to be a name in `FLORIDyn`, I guess it’s not present in `Main` during precompilation?

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [July 27, 2025, 5:04pm UTC](https://discourse.julialang.org/t/function-fails-when-used-in-precompile-workload/131095/3 "2025-07-27T17:04:47Z")

</div>

Shell I use a different module name than Main? I mean, the struct is defined, otherwise the line where `a` is assigned would not work.

---

<div class="post-metadata">

### Author: ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)
#### Post date: [July 27, 2025, 5:21pm UTC](https://discourse.julialang.org/t/function-fails-when-used-in-precompile-workload/131095/4 "2025-07-27T17:21:21Z")

</div>

Precompilation will spawn a new Julia process, so anything you define in the `Main` module can not be accessed when precompiling. Even neglecting precompilation, depending on the state of the user’s `Main` module like this seems like an unusual API choice though. For instance, an approach like this will be inherently type unstable. Why not let the user pass a type explicitly and parametrize on that?

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [July 27, 2025, 5:32pm UTC](https://discourse.julialang.org/t/function-fails-when-used-in-precompile-workload/131095/5 "2025-07-27T17:32:53Z")

</div>

> [@simeonschaub](#):
>
> Why not let the user pass a type explicitly and parametrize on that?

I dispatch on marker structs, like:

```julia-auto
struct Velocity_Constant <: VelModel end

```

The functions then look like this:

```julia-auto
function getWindSpeedT(::Velocity_Constant, WindVel, iT, _)

```

I have many of these functions, they have the same name, but a different type as first parameter. Not my design choice, a consequence of translating Matlab code that was switching the search path for the functions at runtime.

My `Settings` constructor looks like this:

```julia-auto
function Settings(wind::Wind, sim::Sim, con::Con)
    vel_mode = str2type("Velocity_" * wind.input_vel)
    dir_mode = str2type("Direction_" * wind.input_dir)
    turb_mode = str2type("TI_" * wind.input_ti)
    shear_mode = str2type("Shear_" * wind.input_shear)
    cor_dir_mode = str2type("Direction_" * wind.correction.dir)
    cor_vel_mode = str2type("Velocity_" * wind.correction.vel)
    cor_turb_mode = str2type("TI_" * wind.correction.ti)
    iterate_mode = str2type(sim.dyn.op_iteration)
    control_mode = str2type("Yaw_" * con.yaw)
    Settings(vel_mode, dir_mode, turb_mode, shear_mode, cor_dir_mode, cor_vel_mode, cor_turb_mode, 
             iterate_mode, control_mode)
end

```

So I really need the `str2type` function. The structs passed to the `Settings` constructor are created from a yaml settings file.

My only question is, how to write the `str2type` function such that I can use it during precompilation.

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [July 27, 2025, 5:38pm UTC](https://discourse.julialang.org/t/function-fails-when-used-in-precompile-workload/131095/6 "2025-07-27T17:38:56Z")

</div>

> [@ufechner7](#):
>
> My only question is, how to write the `str2type` function such that I can use it during precompilation.

I changed the function to:

```julia-auto
function str2type(name)
    typename = Symbol(name)
    t = getfield(FLORIDyn, typename)
    instance = t()
end

```

And now all works fine!

Thank you!

---

<div class="post-metadata">

### Author: ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)
#### Post date: [July 27, 2025, 5:40pm UTC](https://discourse.julialang.org/t/function-fails-when-used-in-precompile-workload/131095/7 "2025-07-27T17:40:51Z")

</div>

I still don’t understand why you need to create separate types if all that changes are the values in a yaml file. ~~If you want your package to work with precompilation you will have to change your approach, as I said, as-is your design is not compatible with precompilation.~~ I didn’t realize the types were actually defined in your package and not by the user. In that case your approach will work, but the issues around type-stability still stand

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [July 27, 2025, 5:55pm UTC](https://discourse.julialang.org/t/function-fails-when-used-in-precompile-workload/131095/8 "2025-07-27T17:55:35Z")

</div>

Yeah I agree with the change to the parent module of the fixed set of types. Using `Main` seems to weirdly restrict things to REPL work, which goes out the window if the user likes to change contextual modules often or happens to assign different things to the same names.

Not that it’d further help this resolved problem, but the PrecompileTools documentation says:

> There are cases where you might want to precompile code but cannot safely _execute_ that code: for example, you may need to connect to a database, or perhaps this is a plotting package but you may be currently on a headless server lacking a display, etc. In that case, your best option is to fall back on Julia’s own `precompile` function.

though it also explains that you’d need to do more work to discover and write more `precompile` calls for any useful runtime-dispatched callees.
