Migrating code from Matlab: Accessing arrays without allocating


#21

That talk is more about the intricacies of creating your own custom array type — this topic is more general purpose usage. So you’re free to watch that video, but don’t think that it has any magic bullets to understanding here.

The key thing to remember is that broadcasting takes a scalar function and maps it across the elements of the arguments. For the most part, this has allowed us to deprecate the manually “vectorized” functions — we just need to implement the scalar version of the function and then users can decide if they want to map it across an array easily through the dot-syntax.

The biggest API that is a counter-example to that new idiom is indexing. There are a few major disconnects that prevented us from deprecating non-scalar indexing (like A[1:end, 1:end]) in favor of broadcast (these disconnects include logical indexing and the fact that APL indexing returns the cartesian product). When broadcasting and non-scalar indexing collide, you can find yourself in a bit of a challenging area where these two mental models seem so very similar and familiar but don’t quite transfer back and forth. Perhaps by Julia 2.0 we’ll find a way to unify these two modes.

So this means that we currently have two ways to assign one array into a section of another. You can use the indexing semantics with out[1:3] = [1,2,3] (that is, setindex!) or you can use broadcasting semantics with out[1:3] .= [1,2,3] (broadcast!). In this particular case, the two are identical. In some cases, though, you’ll see a big win using broadcasting because it’ll be able to fuse loops with other broadcasted functions in the same expression. That’s the game I’m playing with getindex.((x2,), 3:5, 2). This will call getindex three times: getindex(x2, 3, 2), getindex(x2, 4, 2) and getindex(x2, 5, 2). If I didn’t put x2 in a tuple, then it’d try to call getindex on the elements of x2, which is definitely not what you want. I think of putting it in a tuple as “protecting” x2 itself from participating in the broadcast — instead the tuple will broadcast its single element (x2) across whatever other arguments are provided.