insert not working for stucts?
While I'm able to insert using named tuples, it doesn't seem to work for structs?
julia> using Accessors
julia> struct HelloWorld
greeting::String
name::String
end
julia> x = HelloWorld("hi", "World")
HelloWorld("hi", "World")
julia> lens = @optic _.response
(@optic _.response)
julia> insert(x, lens, "goodbye")
ERROR: MethodError: no method matching insert(::HelloWorld, ::PropertyLens{:response}, ::String)
Closest candidates are:
insert(::Any, ::ComposedFunction, ::Any) at ~/.julia/packages/Accessors/KHKiv/src/optics.jl:223
insert(::NamedTuple, ::PropertyLens{field}, ::Any) where field at ~/.julia/packages/Accessors/KHKiv/src/optics.jl:401
insert(::Any, ::typeof(last), ::Any) at ~/.julia/packages/Accessors/KHKiv/src/functionlenses.jl:8
...
Stacktrace:
[1] top-level scope
What would you expect it to return? For namedtuples, the result is obvious: a namedtuple with one more field added. For structs - not so much...
Fair enough. I was thinking that it would create a modified struct... something along the lines of:
julia> using Accessors
julia> struct HelloWorld
greeting::String
name::String
end
julia> x = HelloWorld("hi", "World")
HelloWorld("hi", "World")
julia> lens = @optic _.response
(@optic _.response)
julia> insert(x, lens, "goodbye")
HelloWorld("hi", "World", "goodbye")
julia>propertynames(insert(x, lens, "goodbye"))
(:greeting, :name, :response)
As with a named tuple, it would add in the field to the struct.
Creating a new struct efficiently is impossible from within a function, I think. And anyway, what's the usecase for this? The new struct would bear no relation to the original one, no methods defined for original HelloWorld would work for the output.
Remember, Accessors is no magic: it's effectively a convenient interface to already available functionality.
Right. I have a scenario where there are nested structs. Buried within the nested structs are some optional extension fields that may or not exist at time of creation. Long story short, structs are created based on known fields however additional extension fields need to be added in at a later time. I was hoping I could use Accessors to insert the optional fields into the existing struct instances. As you said, Acccessors is convenient and a potential three-liner is much more appealing than iterating/unpacking existing struct for modification.
Yeah, thats just not possible in julia, you can't modify a struct. That's one reason julia can be fast vs e.g. Python, structs are basically C structs, not dictionaries.
But if you want the flexibility of a NamedTuple with a type you can dispatch on, just make a struct that wraps a NamedTuple. Then you can do what you want.
Well, the point of Accessors is to update/modify immutable types? Right? It's advertised as such for NamedTupes and "arbitrary structs and nested updates" per documentation. There are examples where immutable structs are modified. In interpreting the responses, is it fair to say that Accessors can update/modify structs but not "insert" or add fields. If so, perhaps make a clarifying remark(s) in the documentation?