A(i,j) instead of A[i,j] leads to weird behavior


Consider the code below.

function dummy()
    A = zeros(2,2)
    for i=1:2
        for j=1:2
            A(i,j) = rand() # should be A[i,j]
    return A

It returns

julia> A=dummy()
A (generic function with 1 method)

which is very weird, since in the REPL writing A(i,j) instead of A[i,j] returns an error.
Is this a bug?

By contrast, if we use A[i,j] = rand() we get

julia> A=dummy()
2×2 Array{Float64,2}:
 0.531469  0.218812
 0.48418   0.581266

as expected.

Note that odd behavior also happens outside of functions, although it seems to have to be inside of a for loop. For example

A = zeros(2,2)
for i=1:2
    for j=1:2
        A(i,j) = rand() # should be A[i,j] = rand()

returns zeros(2,2).
Whereas if I write

A = zeros(2,2); A(1,1) = rand(); A(1,2) = rand(); A(2,1)=rand(); A(2,2)=rand()

I get a syntax error, as expected:

ERROR: syntax: "1" is not a valid function argument name

What is going on?


Never mind! I figured it out. It’s the inline function definition syntax tripping me up.
A(i,j) = rand() is defining a function that maps its 2 args to a random number.

This is a nasty “gotcha” for ex Matlab prorgammers to be aware of!


You’re not the only one:


Using the same syntax for indexing as function calls is a bug in the Matlab syntax. (It leads to strange behavior in edge cases.) At least in Julia, when things go wrong it’s because of a programmer error.


This may get me expelled from class, but occasionally I define this…

(A::Array)(ijk...) = A[ijk...]

Obviously this is a terrible idea! But it shouldn’t break valid Julia code, and would turn the above loop into an error. Which which can be useful on the first pass of trying to hack some Matlab script you found in the gutter into running Julia.

Edit – I lied, it does not produce an error here. Because the for loop makes a new scope. Moving on…


Yeah, we have a nice error message when you try to access A(i, j), but trying to assign into it like this is a much harder case to catch — namely because it actually means something different!