-
Notifications
You must be signed in to change notification settings - Fork 21
Description
This might be similar to #18, but more general.
Accessors.jl
defines macros which can both be used on objects of mutable and immutable types. In general, structs can include other structs building a tree with the fields being the leaf nodes. Therefore, the tree can contain mutable and immutable types.
All the lenses and all the object creation including the copying seem to be necessary in general for completely immutable trees. Yet, it is not necessary (at least for isbits
types) if the path from the leaf node to the root node contains at least one mutable type. In this case pointer arithmetic can be used to modify the field directly (bypassing the constructor).
This can be much more efficient. With the modified version of MemoryMutate.jl, I get a performance ratio of about 3 for the following example:
using MemoryMutate, Accessors, Chairmarks
struct C
d::Float64
e::NTuple{16, Int}
end
mutable struct A
a::Float64
b::Int
c::C
end
obj = A(42.0, 42, C(20.0, ntuple(identity, 16)))
julia> @b @mem $obj.c.d = $21.0
5.849 ns
julia> @b @reset $obj.c.d = $21.0
16.638 ns (2 allocs: 176 bytes)
From the user's perspective, however, it might be nice to have a single interface for these modifications. Otherwise, the user would need to check the above mentioned path through the struct tree to decide about which macro to call. And as Accessors.jl
is by far the more popular package, I think it makes sense to use its interface.
I don't know how to implement this using a lens, because I am not familiar with these. However, it does not seem to be necessary to use a lens. Would such a functionality fit to the scope of Accessors.jl
? Would it need to be implemented using a lens in order to be accepted?