# Should the eachindex function be part of the Indexing interface?

**URL:** <https://discourse.julialang.org/t/should-the-eachindex-function-be-part-of-the-indexing-interface/89296>\
**Category:** Internals & Design\
**Tags:** question, indexing\
**Created:** [October 26, 2022, 11:57am UTC](https://discourse.julialang.org/t/should-the-eachindex-function-be-part-of-the-indexing-interface/89296 "2022-10-26T11:57:04Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![eliascarv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eliascarv/32/22152_2.png) [@eliascarv](https://discourse.julialang.org/u/eliascarv)\
**Post date:** [October 26, 2022, 11:57am UTC](https://discourse.julialang.org/t/should-the-eachindex-function-be-part-of-the-indexing-interface/89296/1 "2022-10-26T11:57:05Z")

</div>

Currently, the Indexing interface is composed of 4 functions:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/3/1/31c37e8e5f198317bce4df9aef05fcb954d06059.png)

However, among these functions, there is not one that returns the valid indexes of the indexable object.

In its documentation, it is shown that the eachindex function is related to AbstractArray. But I think it could be more generic and encompass all indexable objects.

## Example

In this case, let’s use the same example from the documentation:

```julia
struct Squares
  count::Int
end

function Base.getindex(S::Squares, i::Int)
  1 <= i <= S.count || throw(BoundsError(S, i))
  return i*i
end

Base.firstindex(S::Squares) = 1
Base.lastindex(S::Squares) = S.count

squares = Squares(100)

```

With only these methods implemented, the `eachindex` function will not work:

```julia-repl
julia> squares[50]
2500

julia> for s in eachindex(squares)
           println(s)
       end
ERROR: MethodError: no method matching keys(::Squares)
Closest candidates are:
  keys(::OrderedCollections.OrderedSet) at C:\Users\Dev01\.julia\packages\OrderedCollections\PRayh\src\ordered_set.jl:95
  keys(::Test.GenericArray) at C:\Users\Dev01\AppData\Local\Programs\Julia-1.8.1\share\julia\stdlib\v1.8\Test\src\Test.jl:1936
  keys(::Tuple) at tuple.jl:71
  ...
Stacktrace:
 [1] eachindex(itrs::Squares)
   @ Base .\abstractarray.jl:282
 [2] top-level scope
   @ .\REPL[2]:1

```

However, other indexable objects that are not subtypes of `AbtractArray` support the `eachindex` function, such as `Dict`:

```julia-repl
julia> d = Dict(:a => 1, :b => 2)
Dict{Symbol, Int64} with 2 entries:
  :a => 1
  :b => 2

julia> for i in eachindex(d)
           println(d[i])
       end
1
2

```

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [October 26, 2022, 12:25pm UTC](https://discourse.julialang.org/t/should-the-eachindex-function-be-part-of-the-indexing-interface/89296/2 "2022-10-26T12:25:12Z")

</div>

Perhaps the function to extend is `keys`, and not `eachindex`. The latter seems to be an optimized version of `keys` for `AbstractArray`s, which falls back to `keys` for general indexed collections.

In fact, keys are more fundamental than `firstindex` and `lastindex`, as there might not be such a notion for an indexed collection, e.g. dictionaries. The documentation seems to suggest that the latter needs to be defined if one wants to index a collection with `begin` and `end`. Perhaps these may be listed as optional methods.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [October 26, 2022, 9:57pm UTC](https://discourse.julialang.org/t/should-the-eachindex-function-be-part-of-the-indexing-interface/89296/3 "2022-10-26T21:57:30Z")

</div>

I don’t know if I agree @jishnub , it seems that the indexing interface in the docs is incomplete. If a type is indexable according to the described interface then the `eachindex` should work right? It seems that there is something off assuming that `eachindex` is a function that is supposed to work with any indexable.

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [October 27, 2022, 4:08am UTC](https://discourse.julialang.org/t/should-the-eachindex-function-be-part-of-the-indexing-interface/89296/4 "2022-10-27T04:08:47Z")

</div>

Somewhere there is a mention of regret on making `keys` extra special. From the help:

> all valid indices for a arranged in the shape of a itself  
> Note that the keys of an array might not be the most  
> efficient index type; for maximum performance use eachindex.

- `keys` are indices similarly, `eachindex` are indices iterably

imo `RegexMatch` would be better using NamedTuples (`keys` happened to be supported long before NamedTuples).

👍🏼`eachindex` _an iterator that iterates_ relocating to Indexing
