Broadcast call of callables in array

I have an Array of callable structs that return vectors. I would like to call each of these structs with the same argument such that I get a matrix with column i being the vector returned by the callable i.

struct Foo
end
function (f::Foo)(x) return rand(5) end
foos = [Foo() for i in 1:3]
julia> foos.(rand(50))
ERROR: MethodError: objects of type Array{Foo,1} are not callable
Use square brackets [] for indexing an Array.

Using array comprehension returns an array of arrays:

julia> [foo(rand(50)) for foo in foos] |> typeof
Array{Array{Float64,1},1}

The desired outcome would be an Array{Float64,2}. In practice foo returns a CuArray so I get an Array of CuArrays.

Happy birthday!

Broadcasting with foos.(A) doesn’t work since it means calling foos with each element of A, and foos is not callable. Related issue: https://github.com/JuliaLang/julia/issues/22129

A possibility is to concatenate the arrays returned by the generator, using hcat:

hcat((foo(rand(50)) for foo in foos)...)

You can trick the broadcast into doing what you want. Not exactly any clearer than a generator though.

reduce(hcat, (Ref(rand(50)) .|> foos))
1 Like