# \`.\*\` falls back to \`Base.broadcast\` only for identical arguments

**URL:** <https://discourse.julialang.org/t/falls-back-to-base-broadcast-only-for-identical-arguments/3991>\
**Category:** General Usage\
**Created:** [May 30, 2017, 2:47pm UTC](https://discourse.julialang.org/t/falls-back-to-base-broadcast-only-for-identical-arguments/3991 "2017-05-30T14:47:19Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [May 30, 2017, 2:47pm UTC](https://discourse.julialang.org/t/falls-back-to-base-broadcast-only-for-identical-arguments/3991/1 "2017-05-30T14:47:19Z")

</div>

Here’s a weird one:

```julia
struct Testype
    x::Int64
end

import Base.broadcast

Base.broadcast(::typeof(*), t1::Testype, t2::Testype) = (t1.x * t2.x)

t1 = Testype(2)
t2 = Testype(3)

```

Now, if you do `t1 .* t2` everything is fine. However, if you do `t1 .* t1` you get

```julia
ERROR: MethodError: no method matching *(::Testype, ::Testype)
Closest candidates are:
  *(::Any, ::Any, ::Any, ::Any...) at operators.jl:424
Stacktrace:
 [1] (::##3#4)(::Testype) at ./<missing>:0
 [2] broadcast(::Function, ::Testype) at ./broadcast.jl:434

```

It appears that the call to `broadcast(*, ...)` falls back to the `Base` definition only in cases where a repeated argument is given.

Why? How do I circumvent this?

I suppose this might be some special behavior to handle squaring more efficiently, but it’s not exactly transparent to the user how this is being done or what methods he should extend to fix it.

Thanks all.

---

<div class="post-metadata">

**Author:** ![malmaud](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/malmaud/32/29_2.png) [@malmaud](https://discourse.julialang.org/u/malmaud)\
**Post date:** [May 30, 2017, 3:43pm UTC](https://discourse.julialang.org/t/falls-back-to-base-broadcast-only-for-identical-arguments/3991/2 "2017-05-30T15:43:17Z")

</div>

[https://github.com/JuliaLang/julia/issues/22053](https://github.com/JuliaLang/julia/issues/22053)

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [May 30, 2017, 5:02pm UTC](https://discourse.julialang.org/t/falls-back-to-base-broadcast-only-for-identical-arguments/3991/3 "2017-05-30T17:02:29Z")

</div>

Thanks. I’m starting to get the sense that people should not overload `broadcast(::typeof(op), args...)` except in cases where there are explicit loops over `*` (and, in such cases, it’s hard to see why you’d want to).

It seems that the way things are going, if a package implements a Hadamard product or something similar but said product does not involve a loop over `*`, the package should instead use a different operator symbol such as `⊙`.

---

<div class="post-metadata">

**Author:** ![jekbradbury](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jekbradbury/32/953_2.png) [@jekbradbury](https://discourse.julialang.org/u/jekbradbury)\
**Post date:** [May 30, 2017, 6:56pm UTC](https://discourse.julialang.org/t/falls-back-to-base-broadcast-only-for-identical-arguments/3991/4 "2017-05-30T18:56:46Z")

</div>

This ([issue](https://github.com/JuliaLang/julia/issues/22060), [PR](https://github.com/JuliaLang/julia/pull/22063)) should address the issue, right? Eventually we want MXNet.jl and friends to actually make use of broadcast fusion, but for now the underlying library (mshadow) only exposes individual vectorized ops and we should essentially inform the Julia compiler of that limitation through something like this `isfusing` trait. In the case of MXNet/mshadow, that’s enough; I guess it’s possible that another library (or a future improved mshadow) could expose a limited version of broadcast fusion (perhaps only for certain operators) and Julia would have to figure out how to support that without applying fusion in cases where the library can’t understand it…
