# Programatically get return type of \`broadcast\`?

**URL:** <https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071>\
**Category:** General Usage\
**Created:** [December 2, 2020, 12:30am UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071 "2020-12-02T00:30:45Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![jdh62043](https://avatars.discourse-cdn.com/v4/letter/j/e480ec/32.png) [@jdh62043](https://discourse.julialang.org/u/jdh62043)\
**Post date:** [December 2, 2020, 12:30am UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071/1 "2020-12-02T00:30:45Z")

</div>

Is there some way to get what a call to `broadcast` would return, possibly similar to how `promote` works? An example of what I need is something like this:

```julia
using StaticArrays

a1 = SA_F32[1, 2, 3] # SArray{Tuple{3}, Float32, 1, 3}
a2 = SA_F32[1 2 3 4] # SArray{Tuple{1, 4}, Float32, 2, 4}
@assert typeof(a1 .+ a2) == SArray{Tuple{3, 4}, Float32, 2, 12}
@assert typeof(a1 .+ a2) == [some function?](typeof(a1), typeof(b1))
                           # ^^^^^^^^^^^^^^

```

---

<div class="post-metadata">

**Author:** ![hiiroo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hiiroo/32/8820_2.png) [@hiiroo](https://discourse.julialang.org/u/hiiroo)\
**Post date:** [December 2, 2020, 7:33am UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071/2 "2020-12-02T07:33:37Z")

</div>

Have you tried the promote\_type(T, U) function?

---

<div class="post-metadata">

**Author:** ![jdh62043](https://avatars.discourse-cdn.com/v4/letter/j/e480ec/32.png) [@jdh62043](https://discourse.julialang.org/u/jdh62043)\
**Post date:** [December 2, 2020, 7:36am UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071/3 "2020-12-02T07:36:03Z")

</div>

Unfortunately, it does not provide the correct result:

```julia
julia> promote_type(typeof(a1), typeof(a2))
SArray{S,Float32,N,L} where L where N where S<:Tuple

julia> promote_type(typeof(a1), typeof(a2)) == SArray{Tuple{3,4}, Float32, 2, 12}
false

```

---

<div class="post-metadata">

**Author:** ![hiiroo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hiiroo/32/8820_2.png) [@hiiroo](https://discourse.julialang.org/u/hiiroo)\
**Post date:** [December 2, 2020, 8:28am UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071/4 "2020-12-02T08:28:09Z")

</div>

They are not equal, however,

```julia
promote_type(typeof(a1), typeof(a2)) == SArray{Tuple{3,4}, Float32, 2, 12}
false

```

should return true, I guess?

---

<div class="post-metadata">

**Author:** ![malacroi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/malacroi/32/19745_2.png) [@malacroi](https://discourse.julialang.org/u/malacroi)\
**Post date:** [December 2, 2020, 10:45am UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071/5 "2020-12-02T10:45:40Z")

</div>

Note the problem is that `promote_type(typeof(a1),typeof(a2))` in this case is abstract but the RHS is concrete. You do have

```julia
julia> typeof(a1 .+ a2) <: promote_type(typeof(a1),typeof(a2))
true

```

---

<div class="post-metadata">

**Author:** ![hiiroo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hiiroo/32/8820_2.png) [@hiiroo](https://discourse.julialang.org/u/hiiroo)\
**Post date:** [December 2, 2020, 10:49am UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071/6 "2020-12-02T10:49:53Z")

</div>

I’m sorry I was also trying to paste this but forgot to change it 😃

```julia
promote_type(typeof(a1), typeof(a2)) <: SArray{Tuple{3,4}, Float32, 2, 12}

```

This should return true?

---

<div class="post-metadata">

**Author:** ![jdh62043](https://avatars.discourse-cdn.com/v4/letter/j/e480ec/32.png) [@jdh62043](https://discourse.julialang.org/u/jdh62043)\
**Post date:** [December 2, 2020, 6:33pm UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071/7 "2020-12-02T18:33:42Z")

</div>

Makes sense. Do you know if there is a way to get the specific type without doing the actual op? I’ve meanwhile come up with the following hacky way to get it to work, but I’m not knowledgable enough about Julia to identify its shortcomings:

```julia
function vector_op(a, b)
    @. a + b
end

function promote_vectorized(a::DataType, b::DataType)::DataType
    Base.promote_op(vector_op, a, b)
end

@assert typeof(a1 .+ a2) == promote_vectorized(typeof(a1), typeof(a2))

```

For my use case, I think this will work well enough. To briefly summarize, I am stringing together pieces of user-provided code and inserting type checks in between so that if one piece of code is written incorrectly, a nice error is produced before moving on to the other pieces of code, so the error can more easily be identified. I want to use it like this:

```julia
const StereoBuffer = SArray{Tuple{2, 512}, Float32, 2, 1024}
# Check that some_var can be used in math operations with other audio data.
@assert promote_vectorized(typeof(some_var), StereoBuffer) == StereoBuffer

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 2, 2020, 8:15pm UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071/8 "2020-12-02T20:15:07Z")

</div>

Using this you get the dimension of the resulting array:

```julia
julia> StaticArrays.combine_sizes(StaticArrays.broadcast_sizes(a1,a2))
Size(3, 4)

```

which corresponds to this operation on the broadcast:

```julia
julia> StaticArrays.broadcast_size(a1 .+ a2)
Size(3, 4)

```

---

<div class="post-metadata">

**Author:** ![jdh62043](https://avatars.discourse-cdn.com/v4/letter/j/e480ec/32.png) [@jdh62043](https://discourse.julialang.org/u/jdh62043)\
**Post date:** [December 2, 2020, 8:24pm UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071/9 "2020-12-02T20:24:04Z")

</div>

This looks really promising, I think combined with eltype() it would be perfect. I’ll test it out later today.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 2, 2020, 8:43pm UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071/10 "2020-12-02T20:43:27Z")

</div>

I found that by following the path of what `a1 .+ a2` does, with:

```julia
@edit broadcast(+,a1,a2)

```

and seeing the implementation. I could not find exactly how to get the complete output type, though. But it should be possible.

---

<div class="post-metadata">

**Author:** ![jdh62043](https://avatars.discourse-cdn.com/v4/letter/j/e480ec/32.png) [@jdh62043](https://discourse.julialang.org/u/jdh62043)\
**Post date:** [December 6, 2020, 8:07am UTC](https://discourse.julialang.org/t/programatically-get-return-type-of-broadcast/51071/11 "2020-12-06T08:07:09Z")

</div>

I just discovered it is possible to directly use `Base.promote_op` on `broadcast`:

```julia
ty = Base.promote_op(Base.broadcast, typeof(+), typeof(a1), typeof(a2))
@assert ty == typeof(a1 .+ a2)

```

I think this provides the most idiomatic solution.
