# Is there a way to write a function into JLD or other h5 file?

**URL:** <https://discourse.julialang.org/t/is-there-a-way-to-write-a-function-into-jld-or-other-h5-file/77718>\
**Category:** General Usage\
**Tags:** jld2\
**Created:** [March 10, 2022, 8:48pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-write-a-function-into-jld-or-other-h5-file/77718 "2022-03-10T20:48:03Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![vavrines](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vavrines/32/8024_2.png) [@vavrines](https://discourse.julialang.org/u/vavrines)\
**Post date:** [March 10, 2022, 8:48pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-write-a-function-into-jld-or-other-h5-file/77718/1 "2022-03-10T20:48:03Z")

</div>

Wondering if there is a way to write a defined function into file.  
A MWE is

```julia
using JLD2
f(x) = x^2
@save "f.jld2" f

```

For this case, if I close the current session and execute the following code

```julia
using JLD2
@load "f.jld2" f

```

I will always get

```julia
┌ Warning: type Main.#f does not exist in workspace; reconstructing
└ @ JLD2 ~/.julia/packages/JLD2/k9Gt0/src/data/reconstructing_datatypes.jl:369

```

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [March 10, 2022, 11:36pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-write-a-function-into-jld-or-other-h5-file/77718/2 "2022-03-10T23:36:01Z")

</div>

I know BSON works if you make your function an anonymous function:

```julia
using BSON
f = x -> x^2
@save "f.bson" f
# in new session
BSON.@load "f.bson" f
f(3) # 9

```

although it [can’t have](https://github.com/JuliaIO/BSON.jl/issues/39) keyword arguments. I don’t think JLD2 works with any unfortunately, but maybe its [in the works](https://github.com/JuliaIO/JLD2.jl/pull/316).

---

<div class="post-metadata">

**Author:** ![JonasIsensee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonasisensee/32/4704_2.png) [@JonasIsensee](https://discourse.julialang.org/u/JonasIsensee)\
**Post date:** [March 11, 2022, 7:38am UTC](https://discourse.julialang.org/t/is-there-a-way-to-write-a-function-into-jld-or-other-h5-file/77718/3 "2022-03-11T07:38:13Z")

</div>

You’re right. Currently it is not possible.  
The PR you mentioned implemented a working draft at some point. However, internals of functions are complicated, and change between julia versions. e.g. significant changes between 1.6 (current LTS) and 1.7.

Additionally, the julia `Serialization` stdlib is good at this.  
This [PR](https://github.com/JuliaIO/JLD2.jl/pull/377) tests whether JLD2 could, in the future, use the julia serializer under the hood to store objects such as functions. This has a few other potential problems and an API would need to be worked out.

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [March 15, 2022, 4:39pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-write-a-function-into-jld-or-other-h5-file/77718/4 "2022-03-15T16:39:22Z")

</div>

I’ve been struggling with saving and loading anonymous functions recently and haven’t found a nice solution, so thank you for highlighting this ability of BSON.jl.

If I save an anonymous function using BSON in - say Julia 1.2 - and then load it again in Julia 1.7 or 1.8, will that be successful? My understanding was that the internals can change without warning and therefore I might _not_ be able to do this. I have a package-internal storage format that strictly uses only raw JSON (for compatibility concerns) so it might be impossible for me to switch, but I can at least learn from how BSON does it.

What I was really trying to do, and I’d love to get advise on what the right approach is here:

```julia
struct AnonF{FF}
    f::FF # the actual function 
    str::String
end

(F::AnonF)(x) = F.f(x)

```

where `str` stores a string (or may better expression??) specifying the function. (I will always want to wrap the function into a callable object and give it extra functionality, so that’s a separate issue.) Then I’d like to initialize it via

```nohighlight
AnonF("x -> x^2")
# or 
AnonF( :( x -> x^2) )

```

and now I’m looking for functionality to write to JSON or YAML and load it again. This must work robustly and long-term across Julia versions and versions of those packages, and ideally human-readable.

Can this be achieved? If I ignore the `str` “meta-data” then I can generate a function from a expression like this

```nohighlight
macro analytic(fexpr)
          quote
             $(esc(fexpr))
          end
       end

```

and I thought it would be possible to return at the same time a string of the expression, but I didn’t manage to do that?

---

<div class="post-metadata">

**Author:** ![JonasIsensee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonasisensee/32/4704_2.png) [@JonasIsensee](https://discourse.julialang.org/u/JonasIsensee)\
**Post date:** [March 15, 2022, 5:00pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-write-a-function-into-jld-or-other-h5-file/77718/5 "2022-03-15T17:00:44Z")

</div>

Hi @cortner ,  
the “right” version to do this is to use the `Serialization` stdlib. BSON does exactly the same. (Most of the relevant code is copied).  
If you want to embed serialized functions in some format, build a small wrapper so that you can use `Serialization.serialize` to convert it into a binary blob.

I made an experimental PR in JLD2 to test this [https://github.com/JuliaIO/JLD2.jl/pull/377](https://github.com/JuliaIO/JLD2.jl/pull/377)

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [March 15, 2022, 5:09pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-write-a-function-into-jld-or-other-h5-file/77718/6 "2022-03-15T17:09:27Z")

</div>

I see - so basically don’t bother with the analytic expression, just serialize the anonymous function in binary. And will this be compatible across Julia versions?

---

<div class="post-metadata">

**Author:** ![JonasIsensee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonasisensee/32/4704_2.png) [@JonasIsensee](https://discourse.julialang.org/u/JonasIsensee)\
**Post date:** [March 15, 2022, 5:15pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-write-a-function-into-jld-or-other-h5-file/77718/7 "2022-03-15T17:15:30Z")

</div>

little is promised but if i remember correctly, serialized functions all the way from 1.3 (or so) should still be readable.

[https://github.com/JuliaLang/julia/blob/master/stdlib/Serialization/src/Serialization.jl](https://github.com/JuliaLang/julia/blob/master/stdlib/Serialization/src/Serialization.jl)

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [March 15, 2022, 6:40pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-write-a-function-into-jld-or-other-h5-file/77718/8 "2022-03-15T18:40:45Z")

</div>

beautiful - thank you! Just one question: If I load a serialized function from file then it assigns the same number to the resulting anon function as when it was originally serialized. E.g. if I then load it and a `#1` was already defined, it creates another one. This seems weird to me, but I have no idea at all whether I should worry about it??

```julia
julia> f = r -> exp(r)
#1 (generic function with 1 method)

julia> using Serialization

julia> fname = "temp.dat"
"temp.dat"

julia> g = deserialize(fname)
#1 (generic function with 1 method)

```

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [March 15, 2022, 7:23pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-write-a-function-into-jld-or-other-h5-file/77718/9 "2022-03-15T19:23:37Z")

</div>

It seems here might be an alternative answer to my question: [https://github.com/MasonProtter/LegibleLambdas.jl/](https://github.com/MasonProtter/LegibleLambdas.jl/)

~~… or at least partially. I still don’t understand how I can write the expression to a file as a string, load it, parse it and then create a new “legible lambda”.~~

EDIT: any concerns with this approach?

```julia
function write_dict(t::LegibleLambda) 
   buf = IOBuffer()
   show(buf, t)
   return Dict(
         "ex" => "$(t.ex)", # f is reconstructed from ex 
         "meta" => String(take!(buf)) # this will be ignored 
      )
end

function LegibleLambda(D::Dict)
   ex = Meta.parse(D["ex"])
   return LegibleLambda(ex, eval(ex))
end

```
