Broadcasting over structs in 1.0: what am I supposed to do?

Hi all-

I commonly broadcast over structs with the dot syntax. While updating my code, I was dismayed to see this is longer a simple process. Here is a minimum working example just for reference:

mutable struct M
m = M(1)
f(m,x) = x/m.x
y = [1,2,3]

This code results in the following warning:

┌ Warning: broadcast will default to iterating over its arguments in the future. Wrap arguments of
│ type `x::M` with `Ref(x)` to ensure they broadcast as "scalar" elements.
│   caller = ip:0x0
└ @ Core :-1

I was further dismayed because the warning message is confusing. It seems to indicate (1) I will (maybe?) have to use Ref(X) all over my code and (2) something will (might?) change in the future. After digging around, I encountered a long discussion that left me even more confused about the situation and what to do. Do I wrap my arguments like so: f.(Ref(m),y)? Do I simply declare Broadcast.broadcastable(x::M) = Ref(x) for each struct? Both currently work, but will it change? (And for what it’s worth if an extra step is necessary for broadcasting structs would strongly prefer to type Broadcast.broadcastable(x::M) = Ref(x) once rather than Ref(x) all over my code). I’m hoping someone one can clarify the situation so I can know how to proceed

1 Like
julia> Broadcast.broadcastable(m::M) = Ref(m)

julia> f.(m,y)
3-element Array{Float64,1}:

See help on broadcastable and for further information.


Thank you for clarifying. I was looking for this information in the Broadcasting and Vectorization section.

Thanks, but shouldn’t “being broadcasted by Ref” be a default behavior of an instance?

The fact is, only when I use broadcasting, I will remember to define this trivil interface to prevent error.
On the other hand, adding this natural behavior to every struct is too expensive for developer.

Is this discussion serious?!

I will comment back!

1 Like