I am trying to learn from base/broadcast.jl and eventually implement a custom broadcaststyle, which is a bit more involved than can be implemented by the methods in doc. I see the following type gymnastics and am wondering whether I can use a simple @generated
function.
I am wondering what is the downside of using:
@generated function BroadcastStyle(a::A, ::DefaultArrayStyle{N}) where {A<:AbstractArrayStyle{M}} where{M,N}
if M>=N
return :(A(M))
else
return :(A(N))
end
end
instead of:
DefaultArrayStyle(::Val{N}) where N = DefaultArrayStyle{N}()
DefaultArrayStyle{M}(::Val{N}) where {N,M} = DefaultArrayStyle{N}()
BroadcastStyle(a::AbstractArrayStyle{M}, ::DefaultArrayStyle{N}) where {M,N} =
typeof(a)(_max(Val(M),Val(N)))
_max(V1::Val{Any}, V2::Val{Any}) = Val(Any)
_max(V1::Val{Any}, V2::Val{N}) where N = Val(Any)
_max(V1::Val{N}, V2::Val{Any}) where N = Val(Any)
_max(V1::Val, V2::Val) = __max(longest(ntuple(identity, V1), ntuple(identity, V2)))
__max(::NTuple{N,Bool}) where N = Val(N)
longest(t1::Tuple, t2::Tuple) = (true, longest(Base.tail(t1), Base.tail(t2))...)
longest(::Tuple{}, t2::Tuple) = (true, longest((), Base.tail(t2))...)
longest(t1::Tuple, ::Tuple{}) = (true, longest(Base.tail(t1), ())...)
longest(::Tuple{}, ::Tuple{}) = ()
Any help appreciated.
Edit:
After consulting master, the issue is already addressed by this commit. That seems like a miracle to me, thank you Julia team!
However I still see this :
Base.@pure function BroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N}
if Base.typename(A) === Base.typename(B)
return A(Val(max(M, N)))
end
return Unknown()
end
Can you explain why @pure
is necessary?