# What is the best way to avoid world age problem in this case?

**URL:** <https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621>\
**Category:** General Usage\
**Tags:** question, world\_age\
**Created:** [August 11, 2022, 2:16pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621 "2022-08-11T14:16:25Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ali\_Vahdati](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ali_vahdati/32/38715_2.png) [@Ali\_Vahdati](https://discourse.julialang.org/u/Ali_Vahdati)\
**Post date:** [August 11, 2022, 2:16pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/1 "2022-08-11T14:16:25Z")

</div>

I am writing a package that uses a YML file as the user interface. Some parameters in the YML file are numbers which are easy to handle. A few parameters need to be functions. I ask the user to put those functions in some file and refer to that file and the function names within that file in the YML file. For examle:

`functions.jl` contains

```julia
f1(a) = a^2

```

and the YML file contains:

```plaintext
function name: f1
function file: functions.jl

```

In my package, I read and use the parameters using `Base.invokelatest`:

```julia

function read_params(param_file)
  d = YAML.load_file(param_file)
  include(d["function file"])
  return eval(Symbol(d["function name"]))
end

function use_params(param_file)
  func = read_params(param_file)
  return Base.invokelatest(func, 12)
end

```

Is this the best way to solve this problem? What other alternatives would you suggest?  
With this method, I face problems when multiple replicates in parallel.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [August 11, 2022, 2:48pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/2 "2022-08-11T14:48:11Z")

</div>

First question: why do you need functions selected in a YML file, and do you really need that? What are you trying to do? whats the big picture here?

Having user-defined input interacting with the julia method table in ways that world age matters normally ends badly.

---

<div class="post-metadata">

**Author:** ![Ali\_Vahdati](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ali_vahdati/32/38715_2.png) [@Ali\_Vahdati](https://discourse.julialang.org/u/Ali_Vahdati)\
**Post date:** [August 11, 2022, 3:05pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/3 "2022-08-11T15:05:50Z")

</div>

Well, the YML file is where the user defines all the parameters. A simple human readable text file. Some of the parameters are functions -rather than being fixed scalars or vectors- and they cannot be put in the YML file. Do you know a better alternative?

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [August 11, 2022, 3:12pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/4 "2022-08-11T15:12:00Z")

</div>

Back up a little: what are you trying to do at all. What is the user trying to do. Why is a parameter a function. What field even is this!?

I’m trying to avoid X Y problems because this is a classic X Y problem kind of question!

> **[The XY Problem](https://xyproblem.info/)**
>
> Asking about your attempted solution rather than your actual problem

---

<div class="post-metadata">

**Author:** ![Ali\_Vahdati](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ali_vahdati/32/38715_2.png) [@Ali\_Vahdati](https://discourse.julialang.org/u/Ali_Vahdati)\
**Post date:** [August 11, 2022, 3:19pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/5 "2022-08-11T15:19:26Z")

</div>

Sure. This is a package to run a certain agent-based model. The parameters define the agents (age, phenotypes, distribution, etc) and the environment (its size, resources, etc). Some parameters can change stochastically over time, for example, the available food across time and space, hence, they cannot fixed vectors. Food availability, given time and region, is a user-defined function.  
Does this answer your question?

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [August 11, 2022, 3:30pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/6 "2022-08-11T15:30:19Z")

</div>

Yes: what you are talking about is similar to problems in my work (with DynamicGrids.jl).

The easiest solution is to not use YML. You are already using a julia script anyway - functions.jl. What do you get from using both a julia script and a YML file?

For variable sets of parameters to run parallel with the same code, you can use a csv (with only paremeters, never functions). I wrote ModelParameters.jl for loading CSV data into arbitrary model structures to do things like run in parallel with different params.

The other trick is for user defined code is define structs instead of functions, and use the same function that dispatches on them. Then the time of loading the script does not matter, the object type matters. Then they can also include parameters (as fields in the sctruct) that you can vary from a CSV instead of using multiple different functions as you seem to be.

If you are using the same function name with different code but no differences in dispatch, you are going to create some hair pulling issues for users. Try to avoid situations where the state of the method table determines the functionality. Your solution should work or error, and never be silently wrong.

---

<div class="post-metadata">

**Author:** ![Ali\_Vahdati](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ali_vahdati/32/38715_2.png) [@Ali\_Vahdati](https://discourse.julialang.org/u/Ali_Vahdati)\
**Post date:** [August 11, 2022, 3:46pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/7 "2022-08-11T15:46:10Z")

</div>

Great advice! Thanks

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [August 11, 2022, 4:23pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/8 "2022-08-11T16:23:17Z")

</div>

All the advice above is great. Just to solve the problem as it is directly asked, you could define a dictionary of options for the function parameter like

```julia
Dict( "first option" => func1,
        "second option" => func2)

```

And then the user could chose their function by key in the yaml file.

Another thing to consider is keeping everything in Julia. `Base.@kwdef` lets you make a struct that could act basically like a yaml file:

```julia
@Base.kwdef struct ModelParameters
    environment_size = (100, 100)
    people_number = 10_000
    food_at_start = 5_000
    resource_change_function = myresourcefunction
end

```

I think it’s about as human-readable as a yaml file.

---

<div class="post-metadata">

**Author:** ![Ali\_Vahdati](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ali_vahdati/32/38715_2.png) [@Ali\_Vahdati](https://discourse.julialang.org/u/Ali_Vahdati)\
**Post date:** [August 11, 2022, 8:32pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/9 "2022-08-11T20:32:34Z")

</div>

Interesting solution! Thank you!

---

<div class="post-metadata">

**Author:** ![Ali\_Vahdati](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ali_vahdati/32/38715_2.png) [@Ali\_Vahdati](https://discourse.julialang.org/u/Ali_Vahdati)\
**Post date:** [August 28, 2022, 9:41am UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/10 "2022-08-28T09:41:36Z")

</div>

I tried your suggested solution, but I still get the world age problem. I now use a dictionary for the user to input the model parameters.

`params.jl`:

```julia
f1(a::Int) = a^2

parameters = Dict(
  :p1 => f1
)

```

`main.jl`:

```julia
module Model

function read_params(param_file)
  include(param_file)
  return parameters
end

function use_params(param_file)
  parameters = read_params(param_file)
  return parameters[:p1](2)
end

end

```

Running the program:

```julia
include("main.jl")
using Main.Model
Model.use_params("params.jl")

ERROR: MethodError: no method matching f1(::Int64)
The applicable method may be too new: running in world age 32419, while current world is 32420.
Closest candidates are:
  f1(::Int64) at E:\projects\mwe_include\params.jl:1 (method too new to be called from this world context.)      
Stacktrace:
 [1] use_params(param_file::String)
   @ Main.Model E:\mwe_include\main.jl:10
 [2] top-level scope
   @ REPL[3]:1

```

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 28, 2022, 10:12am UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/11 "2022-08-28T10:12:45Z")

</div>

No, the point is that you should just create a callable type and change the parameters each time, not the function type.

```julia
struct MyF{T}
  a::T
end

(f::MyF)(x) = a + x

f = MyF(2) # create f with a=2
f(3) # 2 + 3 = 5

```

---

<div class="post-metadata">

**Author:** ![Ali\_Vahdati](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ali_vahdati/32/38715_2.png) [@Ali\_Vahdati](https://discourse.julialang.org/u/Ali_Vahdati)\
**Post date:** [August 28, 2022, 10:40am UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/12 "2022-08-28T10:40:49Z")

</div>

Thanks. But what should be passed in the parameter file?  
I tried the following and it didn’t work.

`params.jl`:

```julia
struct MyF{T}
  a::T
end

(f::MyF)() = f.a^2

parameters = Dict(
  :p1 => MyF
)

```

`main.jl`:

```julia
function read_params(param_file, x)
  include(param_file)
  f = parameters[:p1](x)
  return f()
end

```

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 28, 2022, 2:01pm UTC](https://discourse.julialang.org/t/what-is-the-best-way-to-avoid-world-age-problem-in-this-case/85621/13 "2022-08-28T14:01:45Z")

</div>

> [@Ali\_Vahdati](#):
>
> Thanks. But what should be passed in the parameter file?

Just the parameters.
