# Custom index arithmetic

**URL:** <https://discourse.julialang.org/t/custom-index-arithmetic/14374>\
**Category:** Internals & Design\
**Tags:** question\
**Created:** [August 31, 2018, 4:55pm UTC](https://discourse.julialang.org/t/custom-index-arithmetic/14374 "2018-08-31T16:55:37Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 31, 2018, 4:55pm UTC](https://discourse.julialang.org/t/custom-index-arithmetic/14374/1 "2018-08-31T16:55:37Z")

</div>

This is a clarifying question about [custom indexing](https://docs.julialang.org/en/stable/devdocs/offset-arrays/#man-custom-indices-1).

If `x::AbstractVector` has a conforming interface, can I assume that that the valid indexes are `firstindex(x):lastindex(x)`, ie they are

1. _integers_ (so nothing wacky like `Float64`s or `Symbol`),
2. forming a _contiguous_ range, so I can do arithmetic on them, at least `index += some_step`.

This is for an algorithm that I find difficult to express in an iterator form using `eachindex`.

Sorry if this is obvious and already clearly discussed in the manual.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [August 31, 2018, 8:24pm UTC](https://discourse.julialang.org/t/custom-index-arithmetic/14374/2 "2018-08-31T20:24:02Z")

</div>

We currently assume that `axes(A::AbstractArray, i) <: AbstractUnitRange` in lots of code (so even tighter than your range assumption), and we also expect axes to have integer elements. I think you’re safe to assume the same. A custom “array” that breaks this will already be in lots of deep water and I’d say they’re fine swimming out there on their own.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 1, 2018, 5:12am UTC](https://discourse.julialang.org/t/custom-index-arithmetic/14374/3 "2018-09-01T05:12:21Z")

</div>

Thanks. Do you think it might be worth documenting this explicitly? I would then open an issue.

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [September 1, 2018, 2:48pm UTC](https://discourse.julialang.org/t/custom-index-arithmetic/14374/4 "2018-09-01T14:48:34Z")

</div>

I also asked myself from time to time what should be assumed about `AbstractArray` indices. I guess its a common question, when writing generic code. So I think it would be good to document this.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 2, 2018, 7:19am UTC](https://discourse.julialang.org/t/custom-index-arithmetic/14374/5 "2018-09-02T07:19:03Z")

</div>

After a close reading of the [Interfaces](https://docs.julialang.org/en/v1/manual/interfaces/) and [Arrays with custom indices](https://docs.julialang.org/en/v1/devdocs/offset-arrays/#man-custom-indices-1) documentation, I saw that both are pretty specific about `axes` returning (tuples of) `AbstractUnitRange`.

I am under the impression that this allows _non-integer_ types though: anything goes that has a `oneunit`, eg I could define

```julia
struct RealUnitRange{T <: Real} <: AbstractUnitRange{T}
    start::T
    stop::T
    len::Int
end

RealUnitRange(start, length::Integer) = RealUnitRange(start, start + length, length)

function Base.getindex(rur::RealUnitRange, i::Int)
    @boundscheck @assert 1 ≤ i ≤ rur.len
    rur.start + i
end

# ...

```

and it would be valid for `axis` to return this. Or the same exercise with, for example, `Dates.Date`.

This means that I cannot rely on arithmetic with integers; I should at least increment with multiples of `oneunit`. Also, in theory, I could be worried about floating point error and similar, since the `eltype` of the range could be anything.

Is this a correct interpretation?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [September 5, 2018, 8:27pm UTC](https://discourse.julialang.org/t/custom-index-arithmetic/14374/6 "2018-09-05T20:27:35Z")

</div>

> [@Tamas\_Papp](#):
>
> I am under the impression that this allows _non-integer_ types though: anything goes that has a `oneunit`

Interesting — you might be right. It’s not something that I’ve personally seen or tried, so I wouldn’t be surprised if such an array would fail in some situations.

One thing we do assume is that `A[axes(A)…] == A`. This means that it also needs to be a valid index type. We also sometimes grab axes from one array and use them to index into another — so it needs to be a valid index type for all array types. It may be possible to extend `to_index` to make that work for a non-integer, but I’d still be surprised if everything just worked.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 6, 2018, 4:41am UTC](https://discourse.julialang.org/t/custom-index-arithmetic/14374/7 "2018-09-06T04:41:10Z")

</div>

Perhaps restricting to `AbstractUnitRange{<:Integer}` for the time being could be a reasonable limitation for the time being.

I think this is worth a clarification, so I will open an issue.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 6, 2018, 4:48am UTC](https://discourse.julialang.org/t/custom-index-arithmetic/14374/8 "2018-09-06T04:48:56Z")

</div>

[https://github.com/JuliaLang/julia/issues/29062](https://github.com/JuliaLang/julia/issues/29062)
