Argument order for setindex! and setproperty! not consistent

This is really minor, but I happened to notice that the argument order is not consistent between setindex! and setproperty!. For example, the methods

setindex!(A::Array{Any,N} where N, x, i::Int64) in Base at essentials.jl:419
setproperty!(x::Type, f::Symbol, v) in Base at sysimg.jl:16

In setindex! the value comes before the index. In setproperty! the symbol comes before the value. Given that the symbol and the index are analogous, it would be nice if they were consistent (although changing either would likely break people’s code)

1 Like

I’ve always found the order of setindex! to be counter-intuitive, but I think there’s a good reason for it: setindex! can actually take multiple index arguments (for example, when you do x[i, j, k] = 3 you are calling setindex!(x, 3, i, j, j). Julia only allows variable numbers of arguments to happen at the end of the list of arguments, so putting the variable number of indices at the end makes sense.

setproperty!, on the other hand, only takes exactly one property and one value, so it doesn’t have this issue. I agree that it’s unfortunate that they’re inconsistent, although I do find the order chosen for setproperty! to be more intuitive.

4 Likes

I agree that it is a wart, and goes against the recommendation of the style guide — the mutated argument should be the first here.

I don’t think there is an open issue, can you please open one? This can only be fixed in 2.0 but should not be forgotten.

1 Like

But it is?

2 Likes

You are right — I did not think this through. It is setproperty! that is actually consistent with the style guide, and setindex! which (technically) isn’t, but @rdeits explained why this makes sense.

So I guess it is fine as it is.

Maybe a solution would be to change setproperty! to mimic setindex! and allow varargs, defined recursively so that setproperty!(x, "foo", :a, :b) would call setproperty!(x.a, "foo", :b) which is called when you type x.a.b = "foo"

Probably not super useful, but it would lead to some consistency, similar to how setindex!(x, "foo", a, b) is equivalent to setindex!(x[a,:], "foo", b) for 2D arrays.

The way to make these consistent seems like it would be to always require a tuple of indices for setindex! but I think people would find that annoying too. Seems like the currrent arrangement is probably the best we can manage.

3 Likes