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

Unhelpful output #27 (generic function with 1 method) #369

Closed
this-josh opened this issue Dec 8, 2022 · 2 comments
Closed

Unhelpful output #27 (generic function with 1 method) #369

this-josh opened this issue Dec 8, 2022 · 2 comments

Comments

@this-josh
Copy link

this-josh commented Dec 8, 2022

I'm finding FileIO's saving less intuitive than it could to be, it's supposed to be save(filename, obj). However, in reality I'm getting

julia> using FileIO #1.16.0
julia> x =zeros(3,3)
3×3 Matrix{Float64}:
 0.0  0.0  0.0
 0.0  0.0  0.0
 0.0  0.0  0.0

julia> save("x.jld2",x)
Error encountered while save File{DataFormat{:JLD2}, String}("x.jld2").

Fatal error:
ERROR: must supply a name for each variable

julia> save("x.jld2",x=x)
#27 (generic function with 1 method)

This last output isn't that helpful, it hasn't saved the file and it gives no suggestion that it hasn't. It suggests to me that I should be running

julia> save("x.jld2",x=x)()

which of coure gives an error

ERROR: MethodError: no method matching (::FileIO.var"#27#28"{Base.Pairs{Symbol, Matrix{Float64}, Tuple{Symbol}, NamedTuple{(:x,), Tuple{Matrix{Float64}}}}, String, Vector{Union{Base.PkgId, Module}}, Symbol})()
Closest candidates are:
  (::FileIO.var"#27#28")(::Any) at ~/.julia/packages/FileIO/aP78L/src/loadsave.jl:149

Trying alternative ways of writing this, none of these save:

julia> save("x.jld2";x=x)
#27 (generic function with 1 method)

julia> save("x.jld2";(x=x))
#27 (generic function with 1 method)

julia> save("x.jld2";(;x=x))
ERROR: syntax: invalid keyword argument syntax "(; x = x,)" around REPL[8]:1

julia> d=(;x=x)
(x = [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0],)

julia> save("x.jld2";d)
#27 (generic function with 1 method)

julia> save("x.jld2";d=d)
#27 (generic function with 1 method)

julia> save("x.jld2",d=d)
#27 (generic function with 1 method)

julia> save("x.jld2",d=d)
#27 (generic function with 1 method)

I appreciate the correct syntax is

julia> save("x.jld2",Dict("x"=>x))

But I think the steps above are more likely for a new user and not one of them gives an error suggesting the object I'm saving must be a Dict. In addition the docs don't mention the word "Dict". Given that
FileIO is just a framework is it practical for the docs to be improved/error messages returned instead of #27 (generic function with 1 method)? I think the generic function message is coming from line 149.

Edit1:

I should add that I went through this workflow as I'm used to doing

julia> using JLD2
julia> jldsave("x.jld2",d=d)

I have also seen the JLD2 readme suggests how to use save and the need for a Dict.

I suppose the main point of this issue is, if line 149 returns #27 (generic function with 1 method) can an error be raised along the lines of You are trying to save a .jld2 file, JLD2.jl is unable to save this file format, please consult their docs.

@ararslan
Copy link
Member

This is because the save(path) method is "curried," i.e. it returns a function that accepts an object as input and calls save(path, object). What you see printed in the REPL is due to how Julia names anonymous functions (see the second paragraph of the relevant manual section). That is to say, what you're observing is expected behavior, though it is apparently not actually documented anywhere except in a comment near the line in the code you linked that save behaves this way.

(I'll note as an aside that I'm personally of the opinion that packages shouldn't provide curried methods and it should be up to the user to obtain whatever unclear syntax they want via macros from separate packages. This is admittedly a rather spicy take that I'm sure almost no one agrees with, but it would at least improve the situation you're observing.)

Removing the aforementioned curried method would be a breaking change, so one possible solution here would be to improve the docstring for save by including something along the lines of

"""
    save(file; kwargs...) -> Function

Return an anonymous function that accepts a single argument `x` as
input and returns `save(file, x; kwargs...)`. Note that `x` should
be savable in the given file type; consult the relevant package
documentation for more information.
"""

@ararslan
Copy link
Member

Actually, there is an existing issue #324 which discusses this case and removing the curried method was already proposed in that thread. 😄 I'll close this issue and further discussion and can be directed to that thread.

@ararslan ararslan closed this as not planned Won't fix, can't repro, duplicate, stale Dec 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants