# Julep: Efficient Hierarchical Mutable Data

**URL:** https://discourse.julialang.org/t/julep-efficient-hierarchical-mutable-data/125190
**Category:** Internals & Design
**Tags:** mutable-structure, rfc
**Created:** [January 25, 2025, 6:51am UTC](https://discourse.julialang.org/t/julep-efficient-hierarchical-mutable-data/125190 "2025-01-25T06:51:04Z")
**Posts on this page:** 1
**Showing post:** 34

<div class="post-metadata">

### Author: ![PatrickHaecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickhaecker/32/222891_2.png) [@PatrickHaecker](https://discourse.julialang.org/u/PatrickHaecker)
#### Post date: [January 30, 2025, 9:46am UTC](https://discourse.julialang.org/t/julep-efficient-hierarchical-mutable-data/125190/34 "2025-01-30T09:46:34Z")

</div>

> I had some time this morning to try my hand at a macro-based solution.

This is indeed impressive macro work!

I used

```julia
mutable struct Part
    a::Float32
end

@with_inline_types mutable struct Whole 
    b::Int32
    part::@inline(Part) 
end

w = Whole(Int32(42), Part(42.0f0))

```

to stay compatible with the rest of the discussion (but great that the solution is tested with nested structs)

Note that I have only a limited understanding of the macro implementation, so please correct points I haven’t evaluated correctly, so I can correct the list.

These are the pros and cons I see :

pros:

- clearly defined constructor semantics
- seems to have ideal memory behavior (only one alloc, clear GC story)
- field access works with nested structs
- preserves user defined `getproperty` for `Whole`:  
`Base.getproperty(w::Whole, s::Symbol) = s === :c ? true : getfield(w, s)`  
`julia> w.c`  
`true`
- Preserves object identity (although I do not understand why)  
`w1 = Whole(Int32(1), Part(1.0))`  
`w2 = Whole(Int32(1), Part(1.0))`  
`julia> w1.part === w1.part !== w2.part === w2.part`  
`true`
- methods involving `Part` can be called (using a `Union` or subtyping):

cons:

- constructor no longer supports type conversion (`Whole(42, Part(42.0)` does not work)
- definition syntax more complicated as macro needed both before struct definition and inside field definition
- returns “wrong” fieldnames:  
`julia> Whole |> fieldnames`  
`(:b, :part__a)`
- returns “wrong” type for substructs: `w.part |> typeof`  
`julia> w.part`  
`PartView{:part, Whole}(Whole(42, 42.0f0))`
- `Part`’s methods needs to accept a `Union` or an abstract type (then `Part` needs to use that, too) to work
- Does not support getting the memory address  
`julia> w1.part |> pointer_from_objref`  
`ERROR: pointer_from_objref cannot be used on immutable objects`
- Returns [different types for multiple fields of the same type](https://discourse.julialang.org/t/julep-efficient-hierarchical-mutable-data/125190/32)

~~So while it does work for the simplest of cases, it seems to be too limited (but I might be using it incorrectly).~~

**Edit** : corrections due to additional input (see below)  
**Edit 2** : added `foobar_lv2`’s limitation

---

_[View the full topic](https://discourse.julialang.org/t/julep-efficient-hierarchical-mutable-data/125190)._
