Comments (6)
Nice! Accessing the leaves of a tree is certainly an important task. As I understand, this assumes that the tree structure is encoded using Tuples
and NamedTuples
. There are many other possible choices, however. What if I have a tree like this:
["some", ["tree", [["encoded", "using"], "vectors"]
Is there a way to let the user supply the tree structure?
from accessors.jl.
Hmm, good question. It's not clear to me in this case even what we'd want the result to look like. Julia infers the type as Array{Any, 1}
, so that doesn't help.
OTOH, if we instead had some nested structs, that should be manageable. StructArrays has some nice tricks for recasting a struct as a named tuple, and after that it reduces to the previous case.
My interest here was to just work with the part that can be manipulated very quickly. So one approach could be to use this as an "outer optic" and pass to something else for each resolved component.
Then I guess part of the question is whether the current results should be considered "leaves". Maybe TupleLeaves
or something is a better name?
from accessors.jl.
Hmm, good question. It's not clear to me in this case even what we'd want the result to look like. Julia infers the type as
Array{Any, 1}
, so that doesn't help.
I would expect bad performance in this case, but the semantics would be:
tree = ["some", ["tree", [["encoded", "using"], "vectors"]
modify(uppercase, tree, Leaves(...)) == ["SOME", ["TREE", [["ENCODED", "USING"], "VECTORS"]
My point was that there are many ways trees are encoded and instead of only supporting one somewhat arbitrary way (descent into Tuples
and NamedTuples
) I would prefer if Accessors.jl could be helpful for all these cases.
My interest here was to just work with the part that can be manipulated very quickly. So one approach could be to use this as an "outer optic" and pass to something else for each resolved component.
I think Recursive goes in this direction. Let's hope inference can handle it 😄
from accessors.jl.
using Accessors
x = (a = [1, 2], b = (c = ([3, 4], [5, 6]), d = [7, 8]));
optic = Recursive(x -> x isa Union{Tuple, NamedTuple}, Elements())
@test modify(sum, x, optic, ) === (a = 3, b = (c = (7, 11), d = 15))
But sadly
@code_warntype modify(sum, x, optic, )
Variables
#self#::Core.Compiler.Const(Accessors.modify, false)
f::Core.Compiler.Const(sum, false)
obj::NamedTuple{(:a, :b),Tuple{Array{Int64,1},NamedTuple{(:c, :d),Tuple{Tuple{Array{Int64,1},Array{Int64,1}},Array{Int64,1}}}}}
optic::Core.Compiler.Const(Recursive{var"#3#4",Elements}(var"#3#4"(), Elements()), false)
Body::NamedTuple{(:a, :b),_A} where _A<:Tuple
1 ─ nothing
│ %2 = Accessors.OpticStyle(optic)::Core.Compiler.Const(Accessors.ModifyBased(), false)
│ %3 = Accessors._modify(f, obj, optic, %2)::NamedTuple{(:a, :b),_A} where _A<:Tuple
└── return %3
from accessors.jl.
Yeah, the reason I started down this path was that statically-typed things should have better performance than I was able to get out of Recursive
. But maybe there's a way to fix that more directly, I'm not sure
from accessors.jl.
You may find RecursiveOfType
recently added to AccessorsExtra helpful:
julia> x = (a = (1, 2), b = (c = ((3, 4), (5, 6)), d = (7, 8)));
julia> o = RecursiveOfType(Tuple{Vararg{Number}})
julia> @btime modify($sum, $x, $o)
2.903 ns (0 allocations: 0 bytes)
(a = 3, b = (c = (7, 11), d = 15))
julia> @btime getall($x, $o)
3.272 ns (0 allocations: 0 bytes)
((1, 2), (3, 4), (5, 6), (7, 8))
from accessors.jl.
Related Issues (20)
- "Concat lens": combine multiple lenses side by side HOT 7
- Assemble an object from optics HOT 7
- `hasproperty()` analogue for optics HOT 3
- IndexLens and changing the container size HOT 3
- `Base.show` ambiguity
- @reset naming convention HOT 4
- fate of insert and delete after these functions get into Base
- How to @reset when the field is known only by its equivalent symbol. HOT 2
- Only a single function argument can be the optic target HOT 3
- [Feature request] Set multiple fields at once HOT 6
- Errors in extensions during precompilation HOT 5
- multi-argument modify HOT 4
- `set` for `StructArray`
- Bad idea, would avoid using this pkg HOT 14
- To be or not to be HOT 3
- Traversal order of `Recursive` HOT 11
- `==` not defined for `IndexLens` HOT 4
- String properties not supported HOT 3
- Tests fail on 1.11 HOT 2
- `@(re)set` very slow when a parametric inner constructor is defined? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from accessors.jl.