Broadcasting like a Number

question
broadcast

#1

I’m trying to create a Type that broadcasts like a Number without being <: Number, see example code below. I tried the following, but broadcasting is returning a zero-dimensional array where Numbers return a Number.

It looks like broadcast is overriden for Number, is overriding the only way to replicate the behaviour of Number? This is unfortunate as I would like to mix-and-match Number and Foo (and of course Vector{<:Number} and Vector{Foo}).

julia> immutable Foo end;

julia> Base.size(::Foo) = ();

julia> Base.getindex(f::Foo,::CartesianIndex{0}) = f;

julia> f(::Number,::Foo) = "foo";

julia> f(::Number,::Number) = "number";

julia> f.(1,Foo())
0-dimensional Array{String,0}:
"foo"

julia> f.(1,2)
"number"

#2

Is this for Fun types?


#3

Yes it is for Fun, and also Domain.


#4

Is there an issue for tracking this? Curious for trying it in OrdinaryDiffEq.jl afterwards.


#5

I just checked, and this does work correctly on julia-0.6, even without defining size() and getindex() for your type:

julia> immutable Foo end;

julia> f(::Number,::Foo) = "foo";

julia> f(::Number,::Number) = "number";

julia> f.(1,Foo())
"foo"

julia> f.(1,2)
"number"

I realize that that doesn’t solve your immediate problem, but at least this will be easier in the future.


#6

Great! I’ll work around it in the meantime (where it came up it can be fixed by having multiple overrides without dealing with broadcast directly.)


#7

Yes, in Julia 0.5 the broadcast function only knows about numbers as scalars. The functionality is greatly expanded in 0.6.


#8

In preparation to 0.6, in 0.5 I am using something like

"Making types work with `broadcast` and dot-syntax in 0.5."
macro ensure_broadcast(typ::Symbol)
    VERSION ≥ v"0.6.0-" && return nothing
    quote
        Base.size(::$typ) = ()
        Base.getindex(f::$typ,::CartesianIndex{0}) = f;
    end
end

but I am wondering if there is going to be something like this in Compat, or is that only backward-looking?