# Redefining a single function broadcast rule?

**URL:** https://discourse.julialang.org/t/redefining-a-single-function-broadcast-rule/97890
**Category:** Performance
**Tags:** broadcast, broadcasting
**Created:** [April 25, 2023, 9:10am UTC](https://discourse.julialang.org/t/redefining-a-single-function-broadcast-rule/97890 "2023-04-25T09:10:54Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![RainerHeintzmann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rainerheintzmann/32/19726_2.png) [@RainerHeintzmann](https://discourse.julialang.org/u/RainerHeintzmann)
#### Post date: [April 25, 2023, 9:10am UTC](https://discourse.julialang.org/t/redefining-a-single-function-broadcast-rule/97890/1 "2023-04-25T09:10:54Z")

</div>

I would like to redefine a single broadcast rule relating to the `coalesce.` broadcast.  
The reason is that the `ShiftedArray` type can return `missing` or `nothing` for out-of-bound shifted access. If the user uses `coalesce.(myshiftedarray)` elementwise on such an array, it would be nice if the array itself changed its type to also `coalesce` the default return type.  
Yet I am struggeling with the broadcasting system to allow for such an effect. The problem is that the `coalesce` function is already to fine-grained and does not see the array. Ideally one would like a coarsegrained broadcasting rule which changes the type, which is anyway hidden in my BroadcastStyle `ShiftedArrayStyle`. But the problem here is that the broadcasting rules do not seem to contain any information about which function is broadcasted.  
So I think one somehow needs to hook directly into the broadcasting by overloading `broadcasted` and check if the function `bc.f` is equal to `coalesce`? But then this also would not yield the correct propagation of `ShiftedArrayStyle`. Any ideas?

---

<div class="post-metadata">

### Author: ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)
#### Post date: [April 25, 2023, 9:25am UTC](https://discourse.julialang.org/t/redefining-a-single-function-broadcast-rule/97890/2 "2023-04-25T09:25:34Z")

</div>

The `Broadcasted` object wraps the function, so perhaps you may dispatch on its type?

```julia
julia> B = Broadcast.broadcasted(+, ones(1));

julia> B.f
+ (generic function with 207 methods)

julia> typeof(B)
Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(+), Tuple{Vector{Float64}}}

```

---

<div class="post-metadata">

### Author: ![RainerHeintzmann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rainerheintzmann/32/19726_2.png) [@RainerHeintzmann](https://discourse.julialang.org/u/RainerHeintzmann)
#### Post date: [April 25, 2023, 10:01am UTC](https://discourse.julialang.org/t/redefining-a-single-function-broadcast-rule/97890/3 "2023-04-25T10:01:01Z")

</div>

Yup. This seems to work:

```julia
function Base.broadcasted(::typeof(coalesce), a::ShiftedArray, b)
    ac = ShiftedArray(a.parent, shifts(a), default=coalesce(default(a), b))
    return invoke(Base.broadcasted, Tuple{typeof(coalesce), AbstractArray, typeof(b)}, coalesce, ac, b)
end
function Base.broadcasted(::typeof(coalesce), a::ShiftedArray, b::AbstractArray)
    error("coalescing a shifted array with another array is intentionally not supported. Please collect before coalescing.")
end
function Base.broadcasted(::typeof(coalesce), a, b::ShiftedArray)
    error("coalescing with a ShiftedArray is intentionally not supported. Please collect before coalescing.")
end

```
