JLSO.jl icon indicating copy to clipboard operation
JLSO.jl copied to clipboard

Deprecate magic keyword constructor for `JLSOFile`

Open nickrobinson251 opened this issue 3 years ago • 2 comments

The currently have a keyword-only JLSOFile constructor which transforms keyword arguments into key => value objects to be serialised... https://github.com/invenia/JLSO.jl/blob/dbf7be646098c800ec53696d40740cd7c0038a69/src/JLSOFile.jl#L70-L79 ...but this is a bit magic, because it fails (or behaves differently) for certain "magic" words (julia, version):

julia> jlso = JLSOFile(x=1)
JLSOFile([x]; version="4.0.0", julia="1.6.0", format=:julia_serialize, compression=:gzip, image="")

julia> haskey(jlso.objects, :x)
true

julia> jlso = JLSOFile(x=1, image="y.png")
JLSOFile([x]; version="4.0.0", julia="1.6.0", format=:julia_serialize, compression=:gzip, image="y.png")

julia> haskey(jlso.objects, :image)  # surprising
false

julia> jlso = JLSOFile(x=1, image=rand(2,2))  # surprising
ERROR: MethodError: Cannot `convert` an object of type Matrix{Float64} to an object of type String

It also means we can't add new keywords in a non-breaking way, since this method already has different behaviour for any keyword that's not already in the "magic" set.

We already have a :key => value pair constructor which seems plenty convenient and more intuitive (no magic): https://github.com/invenia/JLSO.jl/blob/dbf7be646098c800ec53696d40740cd7c0038a69/src/JLSOFile.jl#L89 So i think the magic-keywords constructor can be deprecated to this easily enough, e.g. and have

julia> JLSOFile(:x => 1, :image => rand(2,2))
JLSOFile([image, x]; version="4.0.0", julia="1.6.0", format=:julia_serialize, compression=:gzip, image="")

We should keep the no-args, keywords constructor JLSOFile() or JLSOFile(; kwargs...) (accpeting only the named kwargs, julia, version, image etc.) for creating an empty JLSOFile (i.e. a jlso::JLSOFile with isempty(jlso.objects))

Mentioned in https://github.com/invenia/JLSO.jl/pull/108#discussion_r644123892

nickrobinson251 avatar Jun 02 '21 17:06 nickrobinson251

I have suggested that Checkpoints.jl's checkpoint function should do the opposite that function is both similar and different. https://github.com/invenia/Checkpoints.jl/issues/16

oxinabox avatar Jun 02 '21 18:06 oxinabox

i don't use Checkpoints.jl and don't know anything about the internals, so won't comment on that. My objections here are "it fails (or behaves differently) for certain magic keywords" and "we can't add new keywords in a non-breaking way", so perhaps you can see if those objection apply in the Checkpoints case and if there's a strong enough counter-case. Here i think having only the pairs constructor is preferable to the current situation.

nickrobinson251 avatar Jun 02 '21 18:06 nickrobinson251