Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken function support in julia-0.5 (all functions are generic) #57

Open
timholy opened this issue Feb 28, 2016 · 15 comments
Open

Broken function support in julia-0.5 (all functions are generic) #57

timholy opened this issue Feb 28, 2016 · 15 comments

Comments

@timholy
Copy link
Member

timholy commented Feb 28, 2016

Not sure how we should handle this.

@jeff-regier
Copy link

Are there any workarounds in the meantime?

@StefanKarpinski
Copy link
Member

If you stay on the stable release version of Julia, this shouldn't be an issue.

@jeff-regier
Copy link

I need threading, unfortunately.

On Sun, Mar 6, 2016 at 10:21 AM Stefan Karpinski notifications@github.com
wrote:

If you stay on the stable release version of Julia, this shouldn't be an
issue.


Reply to this email directly or view it on GitHub
#57 (comment).

@StefanKarpinski
Copy link
Member

IIRC, threading was merged before jb/functions, which caused this breakage, so if you checkout the commit right before jb/functions was merged, that might do the trick for you.

@timholy
Copy link
Member Author

timholy commented Mar 7, 2016

@jeff-regier, if you're willing to do some work, the best workaround would be to implement it. I can't guarantee it's even possible, but if there's only one method defined for the object, then by poking around long enough you might be able to grab the AST.

Here's a head start for you:

f = x->x^2
m = first(methods(f))
fieldnames(m)

@ChrisRackauckas
Copy link

Are there any workarounds for this? Will v0.6 change anything about the internals to make this easier/doable?

@MikeInnes
Copy link
Contributor

We shouldn't be grabbing ASTs here, at least in the basic case. Functions are identical to singleton types and should be treated identically. That should make the patch fairly straightforward.

Closures defined in the repl are trickier as the type is obviously transient across sessions. I think it would be ok to not support that case, but we could also take inspiration from Julia serialiser if it does something smarter.

@denizyuret
Copy link

Still getting "ERROR: UndefVarError: isgeneric not defined" in Julia 1.1.1.

@hjkim1304
Copy link

Same here. Anyone have any idea?

@hjkim1304
Copy link

This is basically the error message.

LoadError: UndefVarError: isgeneric not defined
func2expr(::Function) at JLD.jl:845
JLD.AnonymousFunctionSerializer(::Function) at JLD.jl:852
writeas(::Function) at JLD.jl:855
#write#17(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::JLD.JldFile, ::String, ::Function, ::JLD.JldWriteSession) at JLD.jl:514
write(::JLD.JldFile, ::String, ::Function, ::JLD.JldWriteSession) at JLD.jl:514
top-level scope at JLD.jl:1158

@StefanKarpinski
Copy link
Member

It seems like the solution would be to delete the call to isgeneric with the value true.

@xtalax
Copy link

xtalax commented Mar 4, 2021

I'm running in to the same bug in Julia 1.5 when trying to save a Makie.Node{MyCustomType}

@sylvaticus
Copy link

Hello, just one example where this problem shows up:

julia> using JLD
julia> struct Foo
           x::Int64
           f::Function
       end
julia> foo = Foo(1,maximum)
Foo(1, maximum)
julia> jldopen("test.jld", "w") do file
           write(file, "fooj", foo)
       end
ERROR: UndefVarError: isgeneric not defined
Stacktrace:
  [1] func2expr(fun::Function)
    @ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:882
  [2] JLD.AnonymousFunctionSerializer(fun::Function)
    @ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:889
[...]

Is there any workaround possible if you need to save objects whose type includes a function as field ?

@benoitseron
Copy link

I am still experiencing this issue, is there any workaround?

Example of the problem:

using JLD

f(x) = x

save("test.jld", "f", f)

Output:

Error encountered while save FileIO.File{FileIO.DataFormat{:JLD}, String}("test.jld").

Fatal error:
ERROR: UndefVarError: isgeneric not defined
Stacktrace:
  [1] func2expr(fun::Function)
    @ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:882
  [2] JLD.AnonymousFunctionSerializer(fun::Function)
    @ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:889
  [3] writeas(fun::Function)
    @ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:892
  [4] write(parent::JLD.JldFile, name::String, data::Function, wsession::JLD.JldWriteSession; kargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:543
  [5] write(parent::JLD.JldFile, name::String, data::Function, wsession::JLD.JldWriteSession)
    @ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:543
  [6] (::JLD.var"#41#42"{String, typeof(f), Tuple{}})(file::JLD.JldFile)
    @ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:1262
  [7] jldopen(::JLD.var"#41#42"{String, typeof(f), Tuple{}}, ::String, ::Vararg{String}; kws::Base.Pairs{Symbol, Bool, Tuple{Symbol, Symbol}, NamedTuple{(:compatible, :compress), Tuple{Bool, Bool}}})
    @ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:262
  [8] #fileio_save#40
    @ ~/.julia/packages/JLD/6OyJe/src/JLD.jl:1260 [inlined]
  [9] fileio_save(::FileIO.File{FileIO.DataFormat{:JLD}, String}, ::String, ::Function)
    @ JLD ~/.julia/packages/JLD/6OyJe/src/JLD.jl:1256
 [10] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::FileIO.Formatted, ::String, ::Vararg{Any}; options::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:219
 [11] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::FileIO.Formatted, ::String, ::Function)
    @ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:196
 [12] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::Symbol, ::String, ::String, ::Vararg{Any}; options::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:185
 [13] action
    @ ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:185 [inlined]
 [14] #save#20
    @ ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:129 [inlined]
 [15] save(::String, ::String, ::Function)
    @ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:125
 [16] top-level scope
    @ ~/Documents/thesis/one_loop_sampling/code/validation.jl:36
Stacktrace:
 [1] handle_error(e::UndefVarError, q::Base.PkgId, bt::Vector{Union{Ptr{Nothing}, Base.InterpreterIP}})
   @ FileIO ~/.julia/packages/FileIO/DtNtF/src/error_handling.jl:61
 [2] handle_exceptions(exceptions::Vector{Tuple{Any, Union{Base.PkgId, Module}, Vector}}, action::String)
   @ FileIO ~/.julia/packages/FileIO/DtNtF/src/error_handling.jl:56
 [3] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::FileIO.Formatted, ::String, ::Vararg{Any}; options::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:228
 [4] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::FileIO.Formatted, ::String, ::Function)
   @ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:196
 [5] action(::Symbol, ::Vector{Union{Base.PkgId, Module}}, ::Symbol, ::String, ::String, ::Vararg{Any}; options::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:185
 [6] action
   @ ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:185 [inlined]
 [7] #save#20
   @ ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:129 [inlined]
 [8] save(::String, ::String, ::Function)
   @ FileIO ~/.julia/packages/FileIO/DtNtF/src/loadsave.jl:125
 [9] top-level scope
   @ ~/Documents/thesis/one_loop_sampling/code/validation.jl:36

@mkitti
Copy link
Member

mkitti commented Dec 9, 2022

You could use Serialization:
https://docs.julialang.org/en/v1/stdlib/Serialization/#Serialization.serialize

julia> using Serialization

julia> io = IOBuffer()
IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)

julia> serialize(io, x->x^2)

julia> bytes = take!(io)
313-element Vector{UInt8}:
 0x37
 0x4a
 0x4c
 0x11
 0x04
 0x00
 0x00
 0x00
 0x34
 0x33
 0x13
 0x04
 0x00
 0x00
 0x00
 0x00
 0x00
 0x00
 0x00
 0x01
 0x06
 0x23
 0x31
    
 0x00
 0x09
 0xff
 0xff
 0xff
 0xff
 0xff
 0xff
 0xff
 0xff
 0x4c
 0x4c
 0x4c
 0x4c
 0x03
 0x00
 0x03
 0x00
 0x4e
 0x4e
 0xe1
 0x29

julia> io2 = IOBuffer(bytes)
IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=313, maxsize=Inf, ptr=1, mark=-1)

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

julia> g(5)
25

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.