# Design: memoizing functions with composite type arguments

**URL:** <https://discourse.julialang.org/t/design-memoizing-functions-with-composite-type-arguments/5887>\
**Category:** General Usage\
**Tags:** question\
**Created:** [September 14, 2017, 2:50pm UTC](https://discourse.julialang.org/t/design-memoizing-functions-with-composite-type-arguments/5887 "2017-09-14T14:50:30Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [September 14, 2017, 2:50pm UTC](https://discourse.julialang.org/t/design-memoizing-functions-with-composite-type-arguments/5887/1 "2017-09-14T14:50:30Z")

</div>

Hi, I have been troubled by a specific design problem for a few days. The problem is as follows:

I have a function `f`

```julia
struct foo
   data::Matrix{Float64}
end

function f(x::foo)
   ...
end

```

Since `f` is fairly expensive, I want to memoize its results using `Dict`. However, changing `x.data` will not change its hash. In this sense, function `f` may return wrong results because of memoization.

Any suggestions to resolve this problem?

Since `x.data` can be very large, I do not want to memoize the results with `x.data` as keys. The best approach I can think of is to make `x.data` immutable, which I don’t know how to do.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 14, 2017, 4:20pm UTC](https://discourse.julialang.org/t/design-memoizing-functions-with-composite-type-arguments/5887/2 "2017-09-14T16:20:30Z")

</div>

You can either

1. Write a method for `Base.hash` that uses `data`. The default just falls back to `object_id(x)`.

2. Avoid changing values.

While 1. is an immediate fix, and helps you reuse results for structures that share the same matrix, think about 2. in addition. It sometimes leads to more transparent code.

---

<div class="post-metadata">

**Author:** ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)\
**Post date:** [September 14, 2017, 5:12pm UTC](https://discourse.julialang.org/t/design-memoizing-functions-with-composite-type-arguments/5887/3 "2017-09-14T17:12:57Z")

</div>

Thanks, I think I will try to avoid changing values. However, I have a question regarding the first approach: How does hash works for a composite type? Why changing `x.data` does not change `hash(x)`.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 14, 2017, 5:19pm UTC](https://discourse.julialang.org/t/design-memoizing-functions-with-composite-type-arguments/5887/4 "2017-09-14T17:19:29Z")

</div>

Look at the sources, eg

```julia
@edit hash(f, zero(UInt))

```

and you will see what is going on. The fallback method for composite hashes does not actually look into the object.

You can also try

> **[GitHub - JuliaServices/AutoHashEquals.jl: A Julia macro to add == and hash()...](https://github.com/JuliaServices/AutoHashEquals.jl)**
>
> A Julia macro to add == and hash() to composite types. - GitHub - JuliaServices/AutoHashEquals.jl: A Julia macro to add == and hash() to composite types.

if you don’t want to implement hashing yourself.
