# Save user-defined input functions for different simulations

**URL:** <https://discourse.julialang.org/t/save-user-defined-input-functions-for-different-simulations/118461>\
**Category:** General Usage\
**Tags:** fonts\
**Created:** [August 21, 2024, 6:13pm UTC](https://discourse.julialang.org/t/save-user-defined-input-functions-for-different-simulations/118461 "2024-08-21T18:13:51Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![clm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/clm/32/45923_2.png) [@clm](https://discourse.julialang.org/u/clm)\
**Post date:** [August 21, 2024, 6:13pm UTC](https://discourse.julialang.org/t/save-user-defined-input-functions-for-different-simulations/118461/1 "2024-08-21T18:13:51Z")

</div>

I’m running a bunch of simulations, whose inputs and outputs I would like to save, where the user inputs are both numbers and functions. Currently, I save all of my inputs and outputs using JLD2. In a toy example of solving a heat equation, I set up some initial parameters, allow the user to define a source function, and then save the inputs and the outputs,

```julia
N = 10
t_range = (0.0,1.0)
x_range = (0.0,10.0)
temp_source(t) = cos(t)

p = N, t_range, x_range, temp_source
sol = function_that_solves_heat_equation(p)

using JLD2
jldsave("naming_scheme.jld2"; p, sol)

```

This will save everything as intended and allow reproducible outputs. However, if someone else ran this code, I would like to be able to see how they defined `temp_source(t)`. So in this example, I would like to be able to see `cos(t)` – probably as a string? (Or, ideally in a way that scales to more complicated functions with multiple inputs)

So far, I’ve only come up with a workaround that requires the user to input the function twice – once as above, and again in a second line, wrapped in a string,

```julia
temp_source_str = "cos(t)"

```

In addition to being clunky, this introduces another potential source of user error that I would like to avoid.

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [August 21, 2024, 8:19pm UTC](https://discourse.julialang.org/t/save-user-defined-input-functions-for-different-simulations/118461/2 "2024-08-21T20:19:38Z")

</div>

This seems to me like a good usecase for a book-keeping macro. IIUC, you basically want to store the function body symbolically, right? So you could write a macro that does something like this:

```julia
# struct for storage of information
struct UserFunction{F}
    func::F
    source
end

(uf::UserFunction)(args...) = uf.func(args...)

# this macro call
@userfunc temp_source(t) = cos(t)
# then expands to something like
temp_source = UserFunction(t -> cos(t), :(cos(t)))

```

just as a rough sketch (am on mobile)

Addendum: I think you could even automate saving of this with JLD2 by overloading some function. You would then just save the expression. When loading you’d then `eval` the expression to recreate the function object.

---

<div class="post-metadata">

**Author:** ![clm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/clm/32/45923_2.png) [@clm](https://discourse.julialang.org/u/clm)\
**Post date:** [August 22, 2024, 2:06am UTC](https://discourse.julialang.org/t/save-user-defined-input-functions-for-different-simulations/118461/3 "2024-08-22T02:06:30Z")

</div>

I appreciate the insights! Unfortunately, I’m still a Julia amateur, so I can’t figure out how to build that macro myself (or the automated saving to JLD2). If you have any other thoughts or resources that might point me in the right direction that would be great. Thanks!

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [August 22, 2024, 7:17am UTC](https://discourse.julialang.org/t/save-user-defined-input-functions-for-different-simulations/118461/4 "2024-08-22T07:17:15Z")

</div>

Just in case, check also [this post](https://discourse.julialang.org/t/how-do-i-see-whats-inside-a-function/88599/7) out using CodeTracking.

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [August 22, 2024, 8:43am UTC](https://discourse.julialang.org/t/save-user-defined-input-functions-for-different-simulations/118461/5 "2024-08-22T08:43:24Z")

</div>

@rafael.guerra’s suggestion using CodeTracking.jl is likely much easier.

You could simply do:

```julia-repl
julia> using CodeTracking
julia> temp_source(t) = cos(t);
julia> code_string(temp_source, (Float64,))
"temp_source(t) = cos(t)"

julia> f = temp_source # also works when you have the function object in some other variable
temp_source (generic function with 1 method)

julia> code_string(f, (Float64,))
"temp_source(t) = cos(t)"

```

So assuming all these user-defined functions have a known signature, you can get the definitions quite easily 🙂 The docs mention some limitation for complicated functions, but this is probably not an issue for you. I’d just try it 🙂

---

<div class="post-metadata">

**Author:** ![clm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/clm/32/45923_2.png) [@clm](https://discourse.julialang.org/u/clm)\
**Post date:** [August 22, 2024, 8:05pm UTC](https://discourse.julialang.org/t/save-user-defined-input-functions-for-different-simulations/118461/6 "2024-08-22T20:05:25Z")

</div>

Thanks, both. I was having issues with CodeTracking initially (code\_string and code\_expr returning `nothing`), but it seems that issue was only appearing in IJulia. Unsure why that is, as other interactive util commands work fine. I was hoping to build the main interface through a notebook so the outputs are easier to play with, but perhaps that won’t be possible.

In any case, CodeTracking solves the main problem!
