Proposal: syntax for accessing arrays using relative indices

Hi!

Let’s say I want to access 4 elements of an array. Today, I do something like:

data[1200:1203]
data[1200:1200+3]

or

data[i:i+3]

Wouldn’t be nice if we have a syntax to access elements using relative indices? Something like:

data[i+:4]

which will return 4 elements after (and including) data[i]? (This is not a good syntax, since it is currently valid and will return the element data[i+4], I am just without ideas to propose a syntax for that, I just want to raise a discussion about the subject).

What’s wrong with data[i.+(0:3)]?

1 Like

I think the same problem with [i:i+3], you “type” 3 but are accessing 4 elements.

But that’s really always the problem with indexing. I personally would find data[i+:4] to mean data[i:i+3] more confusing.

1 Like

OK, I agree that indexing is problematic, leading to different opinions.

We already have range(i,length=4), which is clearer than an operator syntax.

10 Likes

Ok, I can create a function for that to avoid too much typing. Thanks @stevengj!

There’s an issue (I don’t know where it is off the top of my head) and it suggested using a sort of filtering syntax for indexing.

X[>(5)]

Would get all indices greater than five. I’ve played around with it and really like it but I don’t think it would be a trivial thing to implement at this point.

Base.getindex(a::AbstractVector, f::Function) = filter(f, a)

works and is backwards-compatible since you can’t currently index arrays with functions.

(You’d also have to fix the interaction with @view and similar, e.g. by adding a method for view(::AbstractVector, ::Function).)

5 Likes

I anticipate the difficulty would be dealing with more complex corner cases that result from multidimensional indexing and getting everyone to agree on implementation details. However, I’d be happy to be wrong about this and see it become a standard feature.

Playing around for fun:

julia> struct Offset end

julia> off = Offset()
Offset()

julia> struct Off n end

julia> Base.:(*)(a, ::Offset) = Off(a)

julia> Base.:(:)(a, b::Off) = a:(a+b.n)

julia> 10:5off
10:15
13 Likes

This kind of thing is precisely the reason why I just love this language :slight_smile:

4 Likes