JuliaCollections / JuliaCollections/AbstractTrees.jl

Specify a collection as a leaf

Open
#81 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Julia
Stars
243
Forks
67
PR merge metrics
No merged PRs in 30d

Description

There are cases where I want to treat an iterable object as a leaf of a tree for the sake of iteration or printing.

For example, maybe I have a tree like:

julia> using AbstractTrees

julia> tree = [(:a, :b), [(:b, :c), (:c, :d)]]
2-element Vector{Any}:
 (:a, :b)
 [(:b, :c), (:c, :d)]

julia> Tree(tree)
Vector{Any}
├─ (:a, :b)
│  ├─ :a
│  └─ :b
└─ Vector{Tuple{Symbol, Symbol}}
   ├─ (:b, :c)
   │  ├─ :b
   │  └─ :c
   └─ (:c, :d)
      ├─ :c
      └─ :d

but for the sake of iterating I actually want the elements of type Tuple{Vararg{Symbol}} to be treated like leaves.

Is there currently a way to do that? One possibility is defining a special wrapper type like:

struct Leaf{T}
  data::T
end

AbstractTrees.children(::Leaf) = ()

which we use like:

julia> tree = [Leaf((:a, :b)), [Leaf((:b, :c)), Leaf((:c, :d))]]
2-element Vector{Any}:
 Leaf{Tuple{Symbol, Symbol}}((:a, :b))
 Leaf{Tuple{Symbol, Symbol}}[Leaf{Tuple{Symbol, Symbol}}((:b, :c)), Leaf{Tuple{Symbol, Symbol}}((:c, :d))]

julia> Tree(tree)
Vector{Any}
├─ Leaf{Tuple{Symbol, Symbol}}((:a, :b))
└─ Vector{Leaf{Tuple{Symbol, Symbol}}}
   ├─ Leaf{Tuple{Symbol, Symbol}}((:b, :c))
   └─ Leaf{Tuple{Symbol, Symbol}}((:c, :d))

This is easy enough to do externally, but I was wondering if it seems of interest to have a canonical Leaf type in the package.

Alternatively, maybe there could be an interface like Tree(tree; isleaf=[...]) as a way to specify if something should be considered a leaf for the sake of that tree instance. By default it could be x -> children(x) == () or the isleaf function introduced in #79, but it could be extended to something like x -> (children(x) == ()) || (x isa Tuple{Vararg{Symbol}}) for the example above.

Happy to make a PR if any of this is of interest.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Tree, children, and isleaf entry points named in the issue, and review how they determine whether a node has children. Compare the proposed Leaf wrapper with a per-tree isleaf option; done means selecting and documenting one supported way to treat iterable values as leaves, including the tuple example.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.