# Copy on write?

**URL:** <https://discourse.julialang.org/t/copy-on-write/126021>\
**Category:** General Usage\
**Tags:** memory, design-pattern, deepcopy, ref, smart-pointer\
**Created:** [February 18, 2025, 8:10am UTC](https://discourse.julialang.org/t/copy-on-write/126021 "2025-02-18T08:10:36Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![iago-lito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iago-lito/32/31924_2.png) [@iago-lito](https://discourse.julialang.org/u/iago-lito)\
**Post date:** [February 18, 2025, 8:10am UTC](https://discourse.julialang.org/t/copy-on-write/126021/1 "2025-02-18T08:10:36Z")

</div>

Hello Julia,

I need [copy-on-write](https://en.wikipedia.org/wiki/Copy-on-write) behaviour to protect fields of the large values I’m handing out to my users from cluttering their memory with useless copies.

Is there such thing as a julia `Cow{T}` akin to rust’s [`Cow<T>`](https://doc.rust-lang.org/std/borrow/enum.Cow.html) ?

Should I write it myself with some kind of, I don’t know:

```jl
mutable struct Cow{T}
    _value::T
    _owned::Bool
end

```

then very strict access control to such values ?

(N.B: the `Cow` values themselves would not be exposed to my users so it’d be okay that such a homebrew cow be not fullproof, and just helped me not mutate T without deepcopying it first and without cluttering my sources.)

Any advice ?

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [February 18, 2025, 12:40pm UTC](https://discourse.julialang.org/t/copy-on-write/126021/2 "2025-02-18T12:40:47Z")

</div>

You could use a simple ref-counted container, something like

```julia
mutable struct AtomicInt
       @atomic v::Int
end

mutable struct CowMem{T}
       contents :: Memory{T}
       refcount :: AtomicInt
end

CowMem(::Type{T}, size) where T = CowMem(Memory{T}(undef, size), AtomicInt(1))

function share(cow:: CowMem)
       @atomic cow.refcount.v += 1
       CowMem(cow.contents, cow.refcount)
end

function free(cow:: CowMem)
       @atomic cow.refcount.v += -1
end

function Base.getindex(cow:: CowMem, idx)
       cow.contents[idx]
end

function Base.setindex!(cow:: CowMem, v, idx)
       rc = cow.refcount
       if rc.v != 1
           cow.contents = copy(cow.contents)
           @atomic rc.v += -1
           cow.refcount = AtomicInt(1)
       end
       ctx=cow.contents
       ctx[idx] = v
end

```

Then you can take a “cow-snapshot” with the `share` function, and release snapshots via the free function.

Note that different threads need different cow-snapshots (which are initially backed by the same memory), otherwise this is racy!

Also note that the atomic access in `setindex!` is kinda expensive / hard to optimize. I think there is a good argument that `if (@atomic :unordered rc.v) != 0` is good enough, but it’s very hard to reason about atomic :unordered.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [February 18, 2025, 5:19pm UTC](https://discourse.julialang.org/t/copy-on-write/126021/3 "2025-02-18T17:19:17Z")

</div>

It’s worth bearing in mind that the mutability semantics of Julia and Rust come from different language families. Rust offers immutable or limited mutable references to objects, Julia objects themselves have immutable or mutable types. The ability to mutate `_value::T` means `T` is a mutable type (or if we speak more flexibly about mutation API, it could be a wrapper of one), and we access mutable instances solely by what are effectively unlimited mutable references. We just don’t have the kind of control to pull off `to_mut` for a single type.

Julia also doesn’t have Rust’s automatic `Deref` coercion, which seemlessly unwraps `Cow<T>` for methods taking immutable references to `T`. If you use a wrapper type in Julia, you either have to unwrap it manually first or you reimplement a bunch of methods to do it before repeating the call, and there’s no protection from mutation of a mutable `T`.

The closest thing to protection from mutation is sharing an instance of an immutable type. The user can be forced to use a method to deep-copy to a mutable type for mutation, call it `to_mut` if you like. To share instead of copy the data of an immutable instance (like if you assign it to an inlined element or field), you’d need to wrap it in something like the mutable `Ref`, though you’d also need to do your best to obstruct the user from reassigning it. On top of that, you’d need to reimplement non-mutating methods for both the `Ref`-ed immutable version and mutable version.
