# One-sided ranges in array indexes

**URL:** <https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336>\
**Category:** Internals & Design\
**Tags:** indexing, array\
**Created:** [August 21, 2020, 8:27pm UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336 "2020-08-21T20:27:29Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![derikk](https://avatars.discourse-cdn.com/v4/letter/d/76d3ee/32.png) [@derikk](https://discourse.julialang.org/u/derikk)\
**Post date:** [August 21, 2020, 8:27pm UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/1 "2020-08-21T20:27:29Z")

</div>

Suppose I have an array `a = [1, 2, 3, 4, 5]`.

I can index into it at a single value: `a[2] == 2`. I can index it with a range: `a[2:4] == [2, 3, 4]`. I can even get the whole array back with `a[:] == a`.  
Where this pattern breaks down is when writing a one-sided range: `a[3:] != a[3:5] == [3, 4, 5]`.

Yes, we have `end` for this purpose, and as of v1.4, `begin` for ranges starting at the beginning of an index.

But is there a technical reason why syntax like `a[3:]` can’t be translated to `a[3:end]`, yielding `[3, 4, 5]`? Or similarly, why `a[:3]` can’t become `a[begin:3] == [1, 2, 3]`? This feels cleaner, and is similar to Python slice syntax.

This syntax would even more useful in multidimensional arrays, while remaining unambiguous (as far as I can tell). So instead of `b[3:end, begin:4]`, you’d have `b[3:, :4]`.

Currently, `a[3:] ` yields a range syntax error:  
`ERROR: syntax: missing last argument in "3:" range expression `

However, `a[:3] ` is interpreted as `a[3]`. While this is valid code, I don’t believe that anyone would intentionally write this expecting to get `a[3]`.

Would it be possible to integrate this syntax into Julia without breaking any existing code or adding too much parse logic?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [August 21, 2020, 8:35pm UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/3 "2020-08-21T20:35:59Z")

</div>

> [@derikk](#):
>
> However, `a[:3] ` is interpreted as `a[3]` . While this is valid code, I don’t believe that anyone would intentionally write this expecting to get `a[3]` .

Yes, however, ranges also work with variables so if you have two integers called `a` and `b` then `a:b` is a range from `a` to `b`, however, `:b` is `Symbol("b")`. How you would deal with that?

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [August 21, 2020, 8:37pm UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/4 "2020-08-21T20:37:35Z")

</div>

> [@derikk](#):
>
> This feels cleaner, and is similar to Python slice syntax.

Perhaps because you have a python background? To my, `a[:3]` looks unbalanced.

> [@derikk](#):
>
> This syntax would even more useful in multidimensional arrays, while remaining unambiguous (as far as I can tell).

What if you replace `3` with

```julia
julia> a = [1,2,3,4,5];

julia> i = 3;

julia> a[:i]
ERROR: ArgumentError: invalid index: :i of type Symbol

```

`:i` is a symbol.

Given that writing expressions, characters like `i` are symbols while numbers like `3` are literal integers:

```julia
julia> dump(:((i,3)))
Expr
  head: Symbol tuple
  args: Array{Any}((2,))
    1: Symbol i
    2: Int64 3

```

I’d expect to get the symbol `i` and integer `3` from `:i` and `:3`, respectively.

Also, `a[:i]` is not something you can assume was unintentional, like you might assume for `:3`.

```julia
julia> struct Foo end

julia> Base.getindex(::Foo, x) = x

julia> a = Foo();

julia> a[:i]
:i

```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [August 21, 2020, 8:42pm UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/5 "2020-08-21T20:42:55Z")

</div>

Is it possible you could use `::` for this?

```julia
julia> :(A[3::])
ERROR: syntax: unexpected "]"
Stacktrace:
 [1] top-level scope at none:1

julia> :(A[::3]) |> dump
Expr
  head: Symbol ref
  args: Array{Any}((2,))
    1: Symbol A
    2: Expr
      head: Symbol ::
      args: Array{Any}((1,))
        1: Int64 3

```

I think it’s always an error if nothing comes before. But perhaps it’s too weird?

---

<div class="post-metadata">

**Author:** ![derikk](https://avatars.discourse-cdn.com/v4/letter/d/76d3ee/32.png) [@derikk](https://discourse.julialang.org/u/derikk)\
**Post date:** [August 21, 2020, 8:49pm UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/6 "2020-08-21T20:49:25Z")

</div>

> [@Elrod](#):
>
> Perhaps because you have a python background? To my, `a[:3]` looks unbalanced.

It may be unbalanced, but it is easy to type and easy to read.

As for symbol indices, that’s a valid point. The syntax `a[3:]` may remain unambiguous, and be more frequently needed, but it’s probably too confusing allowing one-sided ranges only in one direction.

> [@mcabbott](#):
>
> Is it possible you could use `::` for this?

While in theory this could work, I think it loses the key advantages of symmetry and discoverability that a single colon would have.

---

<div class="post-metadata">

**Author:** ![derikk](https://avatars.discourse-cdn.com/v4/letter/d/76d3ee/32.png) [@derikk](https://discourse.julialang.org/u/derikk)\
**Post date:** [August 21, 2020, 8:55pm UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/7 "2020-08-21T20:55:18Z")

</div>

Actually, assuming all indices along a given dimension have to be of the same type, shouldn’t it be unambiguous which is meant? For instance, if a given dimension is indexed by symbols, the existing behavior would be retained, whereas if it were indexed by integers, the proposed one-sided range would remain unambiguous.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [August 21, 2020, 9:13pm UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/8 "2020-08-21T21:13:15Z")

</div>

That’s just not how Julia’s parser works. Whether something is a symbol or a range expression needs to be decided at parse time, where no information about types is available. This would also be fairly fragile — an example where this breaks down is DataFrames.jl, where DataFrames can be indexed with symbols as well as ranges. I would also suggest reading [this post by Stefan](https://discourse.julialang.org/t/psa-julia-is-not-at-that-stage-of-development-anymore/44872/4), since this behavior is now fairly established in Julia and found to work quite well, so it is very unlikely this is going to change.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [August 21, 2020, 9:51pm UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/9 "2020-08-21T21:51:36Z")

</div>

I’m certain something like this (not with `:` but maybe `::` as suggested) could be made possible, _however_,

> [@derikk](#):
>
> It may be unbalanced, but it is easy to type and easy to read.

I strongly disagree (I think that’s the python talking 😉 ). Reading  
`b[3:, :5]` or `b[:3, 5:]`  
practically makes me dizzy!

---

<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 22, 2020, 5:42am UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/10 "2020-08-22T05:42:27Z")

</div>

> [@derikk](#):
>
> However, `a[:3] ` is interpreted as `a[3]` . While this is valid code, I don’t believe that anyone would intentionally write this expecting to get `a[3]` .
> 
> Would it be possible to integrate this syntax into Julia without breaking any existing code or adding too much parse logic?

Note that the `a[:x]` syntax would have to work not only for literals like `3`, but general expressions, as it does currently. There you would run into breaking changes as `:` currently quotes the expression. Cf

> [@PSA: Julia is not at that stage of development anymore](https://discourse.julialang.org/t/psa-julia-is-not-at-that-stage-of-development-anymore/44872/):
>
> You heard about this brand new exciting programming language called Julia and have some suggestions for how it should work. Wonderful! We’re happy to have you here and help you learn the language and listen to your ideas! However, please be aware that “new” is a relative term. Yes, Julia is newer than, say, C, which was first created in 1972 and standardized in 1989. It is not, however, new in the sense that it is still being freely designed and changed in arbitrary ways. Julia development start…

---

<div class="post-metadata">

**Author:** ![jonniedie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonniedie/32/12842_2.png) [@jonniedie](https://discourse.julialang.org/u/jonniedie)\
**Post date:** [August 22, 2020, 3:43pm UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/11 "2020-08-22T15:43:53Z")

</div>

In my opinion, the further we are away from Python’s array slicing syntax, the better.

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [August 22, 2020, 4:03pm UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/12 "2020-08-22T16:03:44Z")

</div>

This also seems prone to silent errors. Suppose I really meant to write `mean(a[1:5])` and instead wrote `mean(a[1:])`. Right now this errors, in your proposal it happily runs as `mean(a[1:end])`…undesirable IMO.

---

<div class="post-metadata">

**Author:** ![anon37204545](https://avatars.discourse-cdn.com/v4/letter/a/439d5e/32.png) [@anon37204545](https://discourse.julialang.org/u/anon37204545)\
**Post date:** [August 23, 2020, 11:12am UTC](https://discourse.julialang.org/t/one-sided-ranges-in-array-indexes/45336/13 "2020-08-23T11:12:40Z")

</div>

It’s a matter of personal preference. In Julia readability seems to be generally preferred over codegame-like syntax.

Just compare

- `a[1:5]` vs `a[:5]`

- `a[5:end]` vs `a[5:]`

and you will easily see which one can be understood at a glance.

I think this also goes well with 1-based indexing and `end` instead of `-1`.
