GithubHelp home page GithubHelp logo

`Leaves` optic about accessors.jl HOT 6 OPEN

cscherrer avatar cscherrer commented on May 27, 2024
`Leaves` optic

from accessors.jl.

Comments (6)

jw3126 avatar jw3126 commented on May 27, 2024

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.

cscherrer avatar cscherrer commented on May 27, 2024

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.

jw3126 avatar jw3126 commented on May 27, 2024

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.

jw3126 avatar jw3126 commented on May 27, 2024
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
1nothing%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.

cscherrer avatar cscherrer commented on May 27, 2024

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.

aplavin avatar aplavin commented on May 27, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.