Elementwise operators


#1

What’s actually going on under the hood when using elementwise operators? e.g., z=x.*y.

When I look at the syntax tree, the head is call and arg[1] is :(.*). However, I’m not sure where that symbol is actually defined. It’s not in Main or Base. Using @which gives an error.


#2

The syntax tree is only the first half of the syntax story. The second half happens in lowering, and that’s where the magic occurs:

julia> Meta.@lower z=x.*y
:($(Expr(:thunk, CodeInfo(
 1 ─ %1 = (Base.getproperty)(Base.Broadcast, :materialize)                                                                 │
 │   %2 = (Base.getproperty)(Base.Broadcast, :broadcasted)                                                                 │
 │   %3 = (%2)(*, x, y)                                                                                                    │
 │   %4 = (%1)(%3)                                                                                                         │
 │        z = %4                                                                                                           │
 └──      return %4                                                                                                        │
))))

This belies a good deal of complexity, but that’s the entrance to the rabbit hole.


How to interpret lowered code?
#3

The docs are broadcasting. The documentation on how broadcasting works, or at least how you interact with it, is here:

https://docs.julialang.org/en/v1/manual/interfaces/index.html#man-interfaces-broadcasting-1


#4

Thank you both!