# Invalidation free copyto! depending on destination?

**URL:** <https://discourse.julialang.org/t/invalidation-free-copyto-depending-on-destination/87824>\
**Category:** General Usage\
**Created:** [September 26, 2022, 5:08pm UTC](https://discourse.julialang.org/t/invalidation-free-copyto-depending-on-destination/87824 "2022-09-26T17:08:25Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [September 26, 2022, 5:08pm UTC](https://discourse.julialang.org/t/invalidation-free-copyto-depending-on-destination/87824/1 "2022-09-26T17:08:25Z")

</div>

Hi. i have a type that is not a subtype of `AbstractArray`, but it has a notion of size:

```julia
#basically, vector + metadata
struct SingleParam{T,M}
  names::Vector{String}
  values::Vector{T} #same size as names
  metadata::M   
end

#a constructor that only accepts values. normally the constructor requires names and values to be the same size, but this code is only for demonstration purposes

function SingleParam(values::Vector{T})
  names = [string(i) for i in 1:length(values)]
  return SingleParam{T,Nothing)(names,values,nothing)
end

#same size as the underlying values vector
Base.size(param::SingleParam) = Base.size(param.values)
Base.broadcastable(param::SingleParam) = param.values
Base.BroadcastStyle(::Type{<:SingleParam}) = Broadcast.Style{SingleParam}()

```

and i want to perform implace operations over said struct:

```julia
p = SingleParam(rand(5))
p .= exp.(p) .+ sin.(p) .+ rand(5)

```

one way i found to do this is by defining `copyto!`

```julia
function copyto!(dest::SingleParam,src)
  copyto!(dest.values,src)
end

function copyto!(dest::SingleParam,SingleParam)
  copyto!(dest.values,src.values)
  return dest
end

```

but this does not appear to be the official way. as all the documentation does not seem to cover this case. furthermore, seems that this can cause troubles:

> [@CategoricalArrays forces OpenSpecFun\_jll recompilation](https://discourse.julialang.org/t/categoricalarrays-forces-openspecfun-jll-recompilation/87759/23):
>
> For SentinelArrays, I wonder whether we could find a solution by adding an API to ArrayInterfaceCore. Indeed, the problem to solve is just that CategoricalArrays defines a `copyto!` method dispatching on the destination array, while SentinelArrays defines one on the source array. But all that’s needed is to call the general fallback defined in SentinelArrays, there’s no particular interaction between these two packages. If we could add an API to indicate that SentinelArrays should take precedence all would work fine.

and it appears to be an ambiguous method (in conjunction with StaticArrays):

```julia
copyto!(dest::MyModule.SingleParam, src) in MyModule at C:\Users\user\.julia\dev\MyModule\src\database\params\SingleParam.jl:61, 
copyto!(dest, B::Base.Broadcast.Broadcasted{<:StaticArraysCore.StaticArrayStyle}) in StaticArrays at C:\Users\user\.julia\packages\StaticArrays\NOLon\src\broadcast.jl:65)

```

so my question is, what is the correct way to allow this type of implace operations?

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [September 27, 2022, 8:12pm UTC](https://discourse.julialang.org/t/invalidation-free-copyto-depending-on-destination/87824/2 "2022-09-27T20:12:21Z")

</div>

related:

> <https://github.com/JuliaLang/julia/issues/46933>
>
> the broadcasting docs mention this optional method to define implace broadcast a…ssignment:
> \## Customizing broadcasting
> 
> | Methods to implement | Brief description |
> |:-------------------- |:----------------- |
> |... | ...|
> | \*\*Bypassing default machinery\*\* | |
> | \`Base.copyto!(dest, bc::Broadcasted{DestStyle})\` | Custom implementation of \`broadcast!\`, specializing on \`DestStyle\` |
> | ...| ... |
> 
> But defining \`copyto!(x\<:Any,bc::Broadcasted{DestSyle})\` causes ambiguity errors for any subsequent package that needs to do the same. i found this recently in \`StaticArrays\` + \`DataFrames\` https://github.com/JuliaArrays/StaticArrays.jl/issues/1097 , where \`StaticArrays\` defines \`Base.copyto!(dest, B::Broadcasted{\<:StaticArrayStyle})\`, causing ambiguity errors down the line, while following the docs.

> <https://github.com/JuliaArrays/StaticArrays.jl/issues/1097>
>
> this line:
> https://github.com/JuliaArrays/StaticArrays.jl/blob/17e8c377bf959899…fb756ba349e17fc344a34bc9/src/broadcast.jl#L65
> seems that \_copyto! only special handles methods that have static axes. is is correct to assume that those axes only happen on \`x \<: AbstractArray\` ?. if that is the case, then other type trying to dispatch on \`copyto!\` only needs to define:
> \`\`\`
> copyto!(dest::MyType,bc::Base.Broadcsast.AbstractArrayType{N})
> \`\`\`
> then, if an external package needs to define 
> but the catchall method causes ambiguities in that regard.
> 
> I did a test run of StaticArrays on julia 1.8/windows, and removed that method. all tests passed.
