# Make tab-explorable structure from nested Dict

**URL:** <https://discourse.julialang.org/t/make-tab-explorable-structure-from-nested-dict/57979>\
**Category:** General Usage\
**Created:** [March 25, 2021, 11:28pm UTC](https://discourse.julialang.org/t/make-tab-explorable-structure-from-nested-dict/57979 "2021-03-25T23:28:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [March 25, 2021, 11:28pm UTC](https://discourse.julialang.org/t/make-tab-explorable-structure-from-nested-dict/57979/1 "2021-03-25T23:28:58Z")

</div>

For nothing but the sake of my own and potential users convenience when REPL:ing around, I’d like to turn a nested Dict with symbol keys into something which can be tab-completed all the way down to the leaves.

I have made some experiments with wrapping the Dict in a struct and implementing getproperty and propertynames according to the documentation but I can’t get it to propagate to the nested Dicts/structs. I’m guessing it is because I could not make the return type of getproperty inferable.

Translating the nested `Dict` to a nested `NamedTuple` makes the result tabbable in the desired way with the one remaining issue that I’d like to be able to override some base methods, in particular `show`, and trying to wrap the NamedTuple in a struct puts me back at sqaure one unless I accept an unatural extra hop (i.e `data.wrappednamedtuple.a.wrappednamedtuple.b…).

As a hacky workaround, a marker type and a type alias seems to get me what I want, with the perhaps overcomeable cost that one needs to remember to ignore the first element:

```julia
struct Marker end
MyTabbableStruct{T} = NamedTuple{T, <:Tuple{Marker, Vararg}}

Base.propertynames(t::MyTabbableStruct{T}, private=false) where T = private ? T : T[2:end] 

astabbable(d::Dict) = (;:first=>Marker(), (k => astabbable(v) for (k,v) in d)...)
astabbable(x) = x

julia> tabbable = astabbable(Dict(:a=>1, :b=>2,:c=>Dict(:d=>3, :e=>Dict(:f=>4))));

julia> tabbable.c. [press tab]
d e

```

This seems unecessarily convoluted though. Are there other ways to achieve the same thing?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [March 25, 2021, 11:46pm UTC](https://discourse.julialang.org/t/make-tab-explorable-structure-from-nested-dict/57979/2 "2021-03-25T23:46:15Z")

</div>

There is the package [PropDicts.jl](https://github.com/oschulz/PropDicts.jl) that may be helpful.

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [March 26, 2021, 7:57am UTC](https://discourse.julialang.org/t/make-tab-explorable-structure-from-nested-dict/57979/3 "2021-03-26T07:57:12Z")

</div>

Unfortunately it has the same problem as my first alternative. It does not seem to be anything more than a Dict in a struct and I think julia can’t infer the type of getproperty.

Is there something one can do to get the same behaviour as NamedTuple given a Dict? In case it matters, the number of types the values can have is bounded but not union-splitting small. Its basically most `Number` types, `Dicts` and vectors of those.

---

<div class="post-metadata">

**Author:** ![disberd](https://avatars.discourse-cdn.com/v4/letter/d/8edcca/32.png) [@disberd](https://discourse.julialang.org/u/disberd)\
**Post date:** [May 10, 2021, 4:59pm UTC](https://discourse.julialang.org/t/make-tab-explorable-structure-from-nested-dict/57979/4 "2021-05-10T16:59:05Z")

</div>

> [@DrChainsaw](#):
>
> `tabbable = astabbable(Dict(:a=>1, :b=>2,:c=>Dict(:d=>3, :e=>Dict(:f=>4))));`

Did you ever find a better solution to this?  
I also wanted to achieve something similar with custom struct containing named tuples but found this issue of “tabbability” after the first layer.  
I also tried your working example and verified that it works but I can’t seem to understand how adding this Marker would make it so.  
If not too much of a hassle, could you please share some info/insights on why this woud allow the tabbability?

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [May 10, 2021, 7:19pm UTC](https://discourse.julialang.org/t/make-tab-explorable-structure-from-nested-dict/57979/5 "2021-05-10T19:19:41Z")

</div>

Hi,

I have put this issue aside for now as I was not in need of a real solution.

Adding `Marker` is not what makes it tabbable, its just and ad-hoc (ad-hack?) way of making the result of `astabbable` a type owned by me (i.e `MyTabbableStruct`) so I can define e.g. `Base` methods for it without it being type piracy. This comes at the cost of having to keep pretending it is not there and I’m sure it is against a couple of other conventions as well so it is not really something I would recommend.

If you don’t need this, just use a normal named tuple all the way.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [May 10, 2021, 8:43pm UTC](https://discourse.julialang.org/t/make-tab-explorable-structure-from-nested-dict/57979/6 "2021-05-10T20:43:55Z")

</div>

The code that makes completions work is here.  
You might be able to find a way to convince it to do what you want.  
Or monkey-patch it to do what you want.

> <https://github.com/JuliaLang/julia/blob/e4f79b7167312dab649218b53b84c0829ea0c103/stdlib/REPL/src/REPLCompletions.jl#L650>
