Broadcasting like a Number

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"

Is this for Fun types?

Yes it is for Fun, and also Domain.

1 Like

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

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.

3 Likes

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.)

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

2 Likes

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?