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

insert not working for stucts? #81

Open
diadora77 opened this issue Jan 22, 2023 · 6 comments
Open

insert not working for stucts? #81

diadora77 opened this issue Jan 22, 2023 · 6 comments

Comments

@diadora77
Copy link

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
@aplavin
Copy link
Member

aplavin commented Jan 23, 2023

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...

@diadora77
Copy link
Author

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.

@aplavin
Copy link
Member

aplavin commented Jan 23, 2023

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.

@diadora77
Copy link
Author

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.

@rafaqz
Copy link
Member

rafaqz commented Jan 23, 2023

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.

@diadora77
Copy link
Author

diadora77 commented Jan 29, 2023

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?

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

No branches or pull requests

3 participants