Broadcasting over binary functions
I'm a bit confused by the broadcasting behaviour outlined below. Admittedly, I don't understand the broadcasting machinery, but shouldn't all of these examples (ideally) return Fill objects?
julia> using FillArrays
julia> f(x) = x
f (generic function with 1 method)
julia> g(x, y) = x
g (generic function with 1 method)
julia> f.(Fill(1, 2)) # good
2-element Fill{Int64,1,Tuple{Base.OneTo{Int64}}}:
1
1
julia> g.(Fill(1, 2), 3) # ok
2-element Fill{Int64,1,Tuple{Base.OneTo{Int64}}}:
1
1
julia> g.(Fill(1, 2), "a") # why not a Fill output?
2-element Array{Int64,1}:
1
1
julia> g.(Fill(1, 2), Ref(2))
2-element Array{Int64,1}:
1
1
This should be an easy fit: just need to override BrodcastStyle(::FillStyle, ::AbstractArrayStyle{0})
Can I ask for some more help please? I'm stumbling in the dark. I have
struct FillStyle{N} <: AbstractArrayStyle{N} end
Base.BroadcastStyle(::Type{<:AbstractFill{T, N}}) where {T, N} = FillStyle{N}()
(::Type{<:FillStyle})(::Val{N}) where N = FillStyle{N}()
Base.BroadcastStyle(::FillStyle{N}, ::AbstractArrayStyle{0}) where N = FillStyle{N}()
But I'm getting missing methods and ambiguities. I can fix those, I suppose, but is that what you had in mind? I just don't get the broadcasting machinery.
Ah, I forgot there's no FillStyle yet. Annoyingly, there's no RangeStyle in Base for ranges, so there's not a precedent to follow. What warnings are you getting?
I don't know what to do with this one:
julia> f.(Fill(1, 2))
ERROR: MethodError: no method matching similar(::Base.Broadcast.Broadcasted{
FillArrays.FillStyle{1}, Tuple{Base.OneTo{Int64}},typeof(f),
Tuple{Fill{Int64,1,Tuple{Base.OneTo{Int64}}}}}, ::Type{Int64})
similar doesn't make sense for Fill, does it?
Broadcasting has different levels of overriding, see https://docs.julialang.org/en/v1/manual/interfaces/#man-interfaces-broadcasting-1. For immutable types you want to override at a lower level: that is, override copy(bc::Broadcasted{DestStyle})