# Customizing Broadcasting Recursively for Collections of Arrays

**URL:** <https://discourse.julialang.org/t/customizing-broadcasting-recursively-for-collections-of-arrays/25724>\
**Category:** General Usage\
**Created:** [June 26, 2019, 2:41pm UTC](https://discourse.julialang.org/t/customizing-broadcasting-recursively-for-collections-of-arrays/25724 "2019-06-26T14:41:17Z")\
**Posts on this page:** 1\
**Showing post:** 7

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [June 28, 2019, 6:53am UTC](https://discourse.julialang.org/t/customizing-broadcasting-recursively-for-collections-of-arrays/25724/7 "2019-06-28T06:53:58Z")

</div>

FYI, in terms of automatically broadcasting things on the right hand side, it’s kind of easy to get automatic broadcasting for arbitrary (“well-behaving”) struct. To do this, you can just subtype the following `BroadcastableStruct` (which is just a subset of `BroadcastableCallable` I described [here](https://discourse.julialang.org/t/best-practice-for-broadcastable-callables/21000/4)):

```julia
abstract type BroadcastableStruct end

fieldvalues(obj) = ntuple(i -> getfield(obj, i), fieldcount(typeof(obj)))

# Taken from `Setfield.constructor_of`:
@generated constructor_of(::Type{T}) where T =
    getfield(parentmodule(T), nameof(T))

Broadcast.broadcastable(obj::BroadcastableStruct) =
    Broadcast.broadcasted(
        constructor_of(typeof(obj)),
        map(Broadcast.broadcastable, fieldvalues(obj))...)

```

Usage:

```julia
struct A{T} <: BroadcastableStruct
    a::T
    b::T
end

f(x, y) = A(x.a * y.a, x.b * y.b)
g(x::A) = x.a + x.b

g.(f.(A(ones(3), ones(3)), A(ones(3), ones(3))))

```

Result:

```julia
3-element Array{Float64,1}:
 2.0
 2.0
 2.0

```

Of course, you need to make sure that the construction of the struct is “free” (or define such one and use it via `constructor_of`). It’s just a convenient way to use broadcasting so I guess it does not improve any performance, though (I haven’t checked how it works with the inference etc).

I don’t think it’s hard to define `copyto!(::A{<:AbstractArray{T}}, bc::Broadcasted)` for the case “`eltype`” of `bc` is `A{T}`. But this is a bit more tricky to do at the level of `BroadcastableStruct`.

---

_[View the full topic](https://discourse.julialang.org/t/customizing-broadcasting-recursively-for-collections-of-arrays/25724)._
