# Best practice approach for caching data in objects

**URL:** <https://discourse.julialang.org/t/best-practice-approach-for-caching-data-in-objects/20419>\
**Category:** General Usage\
**Tags:** question, type, design\
**Created:** [February 4, 2019, 9:20am UTC](https://discourse.julialang.org/t/best-practice-approach-for-caching-data-in-objects/20419 "2019-02-04T09:20:10Z")\
**Posts on this page:** 1\
**Showing post:** 5

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [February 4, 2019, 10:55pm UTC](https://discourse.julialang.org/t/best-practice-approach-for-caching-data-in-objects/20419/5 "2019-02-04T22:55:55Z")

</div>

This type of caching is also called lazy initialization. I would go with something similar to your approach 4, but extract the lazy logic to be fully independent/reusable; something like this perhaps:

```julia
mutable struct Lazy{T}
   f::Function
   value::Union{Nothing, T}
   calculated::Bool
   Lazy{T}(f) where T = new{T}(f, nothing, false)
end

function value(z::Lazy{T}) where T
    z.calculated || (z.value = z.f(); z.calculated = true)
    z.value::T
end

```

I used a `calculated` field instead of `isnothing`, in case `T` is `Nothing` (which could make sense if the lazy function doesn’t need a return value, e.g. if modifying some global state). Note that this particular implementation is not thread safe.

Now your example can be written like this:

```julia
struct MyType{T}
   v::Vector{T}
   lims::Lazy{Tuple{T,T}}
   MyType(v::AbstractVector{T}) where T = new{T}(v, Lazy{Tuple{T,T}}(() -> extrema(v)))
end

lims(m::MyType) = value(m.lims)

```

Testing it:

```julia
julia> m = MyType([11, 77, 58, 4, 25, 78, 63, 5, 97, 40]);

julia> lims(m)
(4, 97)

julia> @code_warntype lims(m)
Body::Tuple{Int64,Int64}
1 ─ %1 = (Base.getfield)(m, :lims)::Lazy{Tuple{Int64,Int64}}
│ %2 = invoke Main.value(%1::Lazy{Tuple{Int64,Int64}})::Tuple{Int64,Int64}
└── return %2

```

---

_[View the full topic](https://discourse.julialang.org/t/best-practice-approach-for-caching-data-in-objects/20419)._
