# Conventions for mutable shared structure

**URL:** <https://discourse.julialang.org/t/conventions-for-mutable-shared-structure/5536>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 24, 2017, 11:19am UTC](https://discourse.julialang.org/t/conventions-for-mutable-shared-structure/5536 "2017-08-24T11:19:11Z")\
**Posts on this page:** 5\
**Page:** 1

<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:** [August 24, 2017, 11:19am UTC](https://discourse.julialang.org/t/conventions-for-mutable-shared-structure/5536/1 "2017-08-24T11:19:11Z")

</div>

I have a function which takes a user-defined callable object, say `f`, which when called with a vector of numbers is expected to return the value f(x) and the gradient \nabla f(x) at x. `DiffBase.GradientResult` is a natural choice for the result type, and it should be up to the user to decide whether to use forward or reverse AD, or something completely different.

The question: `ForwardDiff.gradient!` and similar operate by overwriting the _same_ `GradientResult` structure. But I don’t want results of different calls to `f` to share any structure, because that would lead to hideous bugs. The way I see it, I have two interface choices:

1. `f(x)` returns results that may share structure, the consumer `copy`s it. Advantage: even if the user messes up, I am safe.
2. `f(x)` is expected to return non-shared values, taking care of it itself.

Is there a reason one of these fits better into Julia than the other? I am leaning toward (1), since the overhead of `copy` is the least of my concerns ATM. Or are there other options?

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [August 24, 2017, 12:20pm UTC](https://discourse.julialang.org/t/conventions-for-mutable-shared-structure/5536/2 "2017-08-24T12:20:23Z")

</div>

_I may not know much about art …_

> “the consumer copies it”

> > - best not to rest the success of your good work rest on that being true

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [August 24, 2017, 12:50pm UTC](https://discourse.julialang.org/t/conventions-for-mutable-shared-structure/5536/3 "2017-08-24T12:50:11Z")

</div>

If you don’t want the returned values to share state, just return values that don’t share state (which seems to be option 2)?

---

<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:** [August 24, 2017, 1:01pm UTC](https://discourse.julialang.org/t/conventions-for-mutable-shared-structure/5536/4 "2017-08-24T13:01:43Z")

</div>

Certainly, but `f` is supplied by the user, and it is tricky (or nearly impossible?) to test for a structure not being shared. Sharing structure can be a simple user error, and lead to bugs.

BTW, having benchmarked both solutions, the cost of `copy` seems to be below measurement error.

---

<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:** [August 25, 2017, 12:35pm UTC](https://discourse.julialang.org/t/conventions-for-mutable-shared-structure/5536/5 "2017-08-25T12:35:07Z")

</div>

I have been thinking about a mechanism that copies data by default, but allows functions to signal that the data does not share structure. Something like

```julia
struct Unshared{T}
    value::T
end

ensure_unshared(x::Unshared) = x

@generated function ensure_unshared(x)
    :(Unshared($(isbits(x) ? :x : :(deepcopy(x)))))
end

```

which could be used as eg

```julia
struct MyType
    x
    MyType(x::Unshared) = new(x.value)
end

MyType(x) = MyType(ensure_unshared(x))

```

Does this make sense?
