StringIndex idea (Julia 2.0)

This idea can be made more ergonomic by merging it with another idea discussed previously:

Something similar to @jishnub’s OrdinalIndexing could be added to the language—this is almost identical to this thread’s OP, but with a nicer user interface that can generalize to other indexable types. The purpose of OrdinalIndexing is to guarantee 1-based indexing even for OffsetArrays. For example:

my_array = OffsetArray(1:10, -10)
my_array[4th] == 4

Applying this concept here, per-character string indexing could go like:


(This is reminiscent of the my_string.nth(i) function in Rust)

The 4th object (let’s call it OrdinalIndex(4)) would store a single integer representing an ordinal index instead of a positional index. Arithmetic and ranges of OrdinalIndex would work as intuitively expected.

When an OrdinalIndex is added to an Integer, it’s promoted to a PositionOrdinalIndex, which could contain both position_offset and ordinal_index fields like the OP of this thread. For example, 0+6th would construct a PositionOrdinalIndex(0,6) and 6:7th could be PositionOrdinalIndex(6,0):PositionOrdinalIndex(0,7). (for 6th to 7th, use (6:7)th or 6th:7th). Adding PositionOrdinalIndex objects would add both fields, similar to a Complex.

Then, indexing from the end should work like this:


It would also be really awesome for ordered dictionaries, wherein it could be imposed that ::OrdinalIndex and ::PositionOrdinalIndex hashkeys are not permitted, so that the dictionary entries can be accessed in insertion order by ::OrdinalIndex and ::PositionOrdinalIndex-typed indices:

my_ordered_dict[1th:100th] # first 100 entries

Maybe it could also be interesting for accessing sparse matrices—I’m not sure.

I’m agnostic on names btw, and as @StefanKarpinski ponders above it might not be worthwhile to maintain a OrdinalIndex type separate from PositionOrdinalIndex since the position will often be const-propped anyway: using only the latter would make the implementation of this idea analogous to the representation of complex numbers (wherein all imaginary numbers are represented as Complex even with zero real component; similar to im ≡ Complex(false,true) we would define const th = PositionOrdinalIndex(false,true)).