# Overload broadcasting for custom struct?

**URL:** https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240
**Category:** General Usage
**Created:** [June 29, 2020, 11:20am UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240 "2020-06-29T11:20:21Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)
#### Post date: [June 29, 2020, 11:20am UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/1 "2020-06-29T11:20:21Z")

</div>

Hello!

I have a struct defined as:

```julia
struct T3{T}
           x::T
           y::T
           z::T
end

```

I want to overload it such that when I write:

```julia
T3(1,1,1) .* 5 = T3(5,5,5)

```

But I do not know how to overload “.\*”. Can anyone help?

Kind regards

---

<div class="post-metadata">

### Author: ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)
#### Post date: [June 29, 2020, 11:33am UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/2 "2020-06-29T11:33:02Z")

</div>

Here is the specification of the interface: [Interfaces · The Julia Language](https://docs.julialang.org/en/v1/manual/interfaces/#man-interfaces-broadcasting-1).

However, I would say that in general customizing broadcasting is an advanced topic. For example if you want to have a look how much code was needed to add broadcasting to DataFrames.jl you can have a look here: [https://github.com/JuliaData/DataFrames.jl/blob/master/src/other/broadcasting.jl](https://github.com/JuliaData/DataFrames.jl/blob/master/src/other/broadcasting.jl).

---

<div class="post-metadata">

### Author: ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)
#### Post date: [June 29, 2020, 11:34am UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/3 "2020-06-29T11:34:31Z")

</div>

If do not exactly understand what you want to achieve.

If you define the \* operator for a `T3{T}` like this:

```julia
struct T3{T}
           x::T
           y::T
           z::T
end
import Base.*
function (*)(t3::T3{T}, n::Number) where {T}
    return T3{T}(t3.x*n,t3.y*n,t3.z*n)
end  

```

Then you can write:

```julia

julia> t=T3{Float64}(3,4,5)
T3{Float64}(3.0, 4.0, 5.0)

julia> t*5
T3{Float64}(15.0, 20.0, 25.0)

```

This can be broadcasted for a collection of `t3`:

```julia

julia> vt=[T3{Float64}(1,2,3),T3{Float64}(4,5,8),T3{Float64}(7,8,9)]
3-element Array{T3{Float64},1}:
 T3{Float64}(1.0, 2.0, 3.0)
 T3{Float64}(4.0, 5.0, 8.0)
 T3{Float64}(7.0, 8.0, 9.0)

julia> vt.*=5
3-element Array{T3{Float64},1}:
 T3{Float64}(5.0, 10.0, 15.0)
 T3{Float64}(20.0, 25.0, 40.0)
 T3{Float64}(35.0, 40.0, 45.0)

```

---

<div class="post-metadata">

### Author: ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)
#### Post date: [June 29, 2020, 11:37am UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/4 "2020-06-29T11:37:46Z")

</div>

Broadcasting might be useful to define if @Ahmed_Salih wanted to take advantage of fusion in broadcasting (but as I have commented - this is an advanced topic so probably not the first thing to start with).

---

<div class="post-metadata">

### Author: ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)
#### Post date: [June 29, 2020, 11:47am UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/5 "2020-06-29T11:47:56Z")

</div>

Thanks @LaurentPlagne, that works for me, thanks for showing me how to use it as well!

@bkamins it was a bit more advanced than I thought, but I need to learn somehow 🙂 Fun to know this is possible in Julia

---

<div class="post-metadata">

### Author: ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)
#### Post date: [June 29, 2020, 11:49am UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/6 "2020-06-29T11:49:37Z")

</div>

@LaurentPlagne just curious, is it possible to make it so that the order of multiplication does not matter?

It allows me to do T3 \* number, but not number \* T3

Kind regards

---

<div class="post-metadata">

### Author: ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)
#### Post date: [June 29, 2020, 12:07pm UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/7 "2020-06-29T12:07:02Z")

</div>

Glad that is useful !  
For your second question see the discussion here

> [@Why do we need to define separate methods for commutative binary operators?](https://discourse.julialang.org/t/why-do-we-need-to-define-separate-methods-for-commutative-binary-operators/42044):
>
> Eg: julia\> struct abc x :: Int end julia\> Base.:(+)(a::abc, b::Int) = abc(a.x + b) julia\> abc(1) + 1 abc(2) julia\> 1 + abc(1) ERROR: MethodError: no method matching +(::Int64, ::abc) julia\> Base.:(==)(a::abc, b::Int) = a.x == b julia\> abc(1) == 1 true julia\> 1 == abc(1) false Shouldn’t the second method in each case automatically be defined in terms of the first? This breaks commutativity in case of the equality. A missing method would have been better than this instead of …

---

<div class="post-metadata">

### Author: ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)
#### Post date: [June 29, 2020, 12:17pm UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/8 "2020-06-29T12:17:14Z")

</div>

Thanks for the explanation! It makes more sense now that not in all cases it is wanted to have commutative properties. I didn’t completely understand the point of having “number as subtype”, but I think I will stick to your approach for now.

Kind regards

---

<div class="post-metadata">

### Author: ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)
#### Post date: [June 29, 2020, 1:11pm UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/9 "2020-06-29T13:11:21Z")

</div>

Note that it is not too long to add;

```julia
 (*)(n::Number, t3::T3{T}) where {T} = t3*n

```

Concerning the `n::Number` type anotation, I am not sure that it is idiomatic.  
The type annotations are of special interest to organize the dispatch of the methods (as it is the case for the `t3::T3{T}` argument.

Here, since we do not do something specific with the `Number`s, it maybe better to let it without annotations.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [June 29, 2020, 5:45pm UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/10 "2020-06-29T17:45:47Z")

</div>

> [@LaurentPlagne](#):
>
> `(*)(n::Number, t3::T3{T}) where {T} = t3*n`

You don’t need the type parameter `T` and the `where` clause here, since you’re not using it.

---

<div class="post-metadata">

### Author: ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)
#### Post date: [June 29, 2020, 5:56pm UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/11 "2020-06-29T17:56:05Z")

</div>

Thanx ! It takes time to forgot about the C++ verbosity 😃

```julia
(*)(n, t3::T3) = t3*n

```

---

<div class="post-metadata">

### Author: ![djturizo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djturizo/32/35005_2.png) [@djturizo](https://discourse.julialang.org/u/djturizo)
#### Post date: [February 12, 2024, 11:13pm UTC](https://discourse.julialang.org/t/overload-broadcasting-for-custom-struct/42240/12 "2024-02-12T23:13:44Z")

</div>

I hate reviving this thread, but it shows often in search engines, so other people may benefit from this. PR [#26891](https://github.com/JuliaLang/julia/pull/26891) implemented a data structure for fused broadcasting. This means we can overload this structure to specialize broadcasted operations. In OP’s example this would be done as:

```julia
struct T3{T}
           x::T
           y::T
           z::T
end
function Broadcast.broadcasted(::typeof(*), a::T3{T}, b) where T
    return T3{T}(a.x*b, a.y*b, a.z*b)
end

```

Then:

```julia
julia> T3(1,1,1) .* 5
T3{Int64}(5, 5, 5)

```

Notice that

```julia
julia> 5 .* T3(1,1,1)
ERROR: MethodError: no method matching length(::T3{Int64})
...

```

The overloaded method is not commutative. If you also want commutativity you also need to overload the reversed case:

```julia
function Broadcast.broadcasted(::typeof(*), a, b::T3{T}) where T
    return b .* a
end

```

Then

```julia
julia> 5 .* T3(1,1,1)
T3{Int64}(5, 5, 5)

```

While I think the accepted answer is the most practical, this is the answer to do exactly what OP asked to (overload a broadcasted operator).
