# Any way to call \`getindex(v, end)\`?

**URL:** <https://discourse.julialang.org/t/any-way-to-call-getindex-v-end/113056>\
**Category:** General Usage\
**Tags:** question\
**Created:** [April 17, 2024, 10:21am UTC](https://discourse.julialang.org/t/any-way-to-call-getindex-v-end/113056 "2024-04-17T10:21:47Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [April 17, 2024, 10:21am UTC](https://discourse.julialang.org/t/any-way-to-call-getindex-v-end/113056/1 "2024-04-17T10:21:47Z")

</div>

If we have a vector `v` we can get the last element with `v[end]`.  
However that seems not to work with the equivalent `getindex`:

```julia
julia> v = rand(3);

julia> v[end]; # works

julia> getindex(v , end) #errors
ERROR: ParseError:
# Error @ REPL[37]:1:14
getindex(v , end) #errors
# └ ── Expected `)`
Stacktrace:
 [1] top-level scope
   @ none:1

```

Anyway to get that going ?

The real use case is when using broadcasting with vector of vectors.  
E.g. let’s say we want to get the last element from every vector

```julia
julia> vv = [rand(x) for x in rand(1:3, 3)]
3-element Vector{Vector{Float64}}:
 [0.37207620800228525, 0.8818089700283445, 0.39908834330666254]
 [0.35994314266508654]
 [0.38387950974422036, 0.2776285863311928, 0.403809461353824]

julia> getindex.(vv, length.(vv)) # currect working version
3-element Vector{Float64}:
 0.39908834330666254
 0.35994314266508654
 0.403809461353824

julia> getindex.(vv, end) # desirable that errors
ERROR: ParseError:
# Error @ REPL[40]:1:15
getindex.(vv, end) # desirable that errors
# └ ── Expected `)`
Stacktrace:
 [1] top-level scope
   @ none:1

```

I would like to avoid `length.(vv)` and since I know that the infastructure for `end` is there, it seems like there should be some way to access it for such cases…

---

<div class="post-metadata">

**Author:** ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)\
**Post date:** [April 17, 2024, 10:25am UTC](https://discourse.julialang.org/t/any-way-to-call-getindex-v-end/113056/2 "2024-04-17T10:25:00Z")

</div>

> [@filchristou](#):
>
> `getindex.(vv, length.(vv))`

What about

```julia
last.(vv)

```

?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [April 17, 2024, 10:25am UTC](https://discourse.julialang.org/t/any-way-to-call-getindex-v-end/113056/3 "2024-04-17T10:25:53Z")

</div>

`end` in indexing expressions just lowers to `lastindex`. That is, `v[end]` is lowered to `getindex(v, lastindex(v))`:

```julia
julia> Meta.@lower v[end]
:($(Expr(:thunk, CodeInfo(
1 ─ %1 = v
│ %2 = v
│ %3 = Base.lastindex(%2)
│ %4 = Base.getindex(%1, %3)
└── return %4
))))

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 17, 2024, 1:16pm UTC](https://discourse.julialang.org/t/any-way-to-call-getindex-v-end/113056/4 "2024-04-17T13:16:41Z")

</div>

> [@Sukera](#):
>
> ```julia
> 1 ─ %1 = v
> │ %2 = v
> 
> ```

What version of Julia are you on? In 1.10.2, the lowered code only evaluates the array expression once:

```julia
julia> Meta.@lower v[end]
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope`
1 ─ %1 = v
│ %2 = Base.lastindex(v)
│ %3 = Base.getindex(%1, %2)
└── return %3
))))

```

which is obviously important for something like `foo()[end]` where computing the array does work (or worse, has side effects).

Hmm, looks like Julia `master` (1.12.0-DEV.360) replicates your results, though thankfully it only computes the array once if it’s more than a variable reference:

```julia
julia> Meta.@lower v[end]
:($(Expr(:thunk, CodeInfo(
1 ─ %1 = v
│ %2 = v
│ %3 = Base.lastindex(%2)
│ %4 = Base.getindex(%1, %3)
└── return %4
))))

julia> Meta.@lower foo()[end]
:($(Expr(:thunk, CodeInfo(
1 ─ %1 = foo
│ %2 = (%1)()
│ %3 = Base.lastindex(%2)
│ %4 = Base.getindex(%2, %3)
└── return %4

```

Not sure why it became more verbose in the `v[end]` case, but it looks harmless.

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [April 17, 2024, 1:35pm UTC](https://discourse.julialang.org/t/any-way-to-call-getindex-v-end/113056/5 "2024-04-17T13:35:50Z")

</div>

`last` returns the last batch of elements. For example, it would be even more complex to get the second to last element. Sukera’s `lastindex` is the exact equivalent.

---

<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:** [April 17, 2024, 3:27pm UTC](https://discourse.julialang.org/t/any-way-to-call-getindex-v-end/113056/6 "2024-04-17T15:27:38Z")

</div>

> [@filchristou](#):
>
> since I know that the infastructure for `end` is there, it seems like there should be some way to access it for such cases

I don’t think anyone has really answered this aspect of your question, but the answer is that `end` is a **syntax** keyword with exactly two uses: closing blocks (e.g., `begin`, `if`, etc) and this special case in `[]` ref expressions. You can’t even parse expressions that use `end` inside function calls like that, let alone “lower” them to their `lastindex` meaning.

```julia-repl
julia> Meta.parse("getindex(A, end)")
ERROR: ParseError:
# Error @ none:1:13
getindex(A, end)
# └ ── Expected `)`

```

This means it’s not even possible to make a macro that could do this transformation like `@m getindex(A, end)`.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 17, 2024, 4:21pm UTC](https://discourse.julialang.org/t/any-way-to-call-getindex-v-end/113056/7 "2024-04-17T16:21:57Z")

</div>

> [@mbauman](#):
>
> This means it’s not even possible to make a macro that could do this transformation like `@m getindex(A, end)`.

However, you could write a macro that goes in the other direction, transforming e.g. `@bcast A[end]` to `getindex.(A, lastindex(A))`, similar to `@.`.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [April 17, 2024, 4:35pm UTC](https://discourse.julialang.org/t/any-way-to-call-getindex-v-end/113056/8 "2024-04-17T16:35:17Z")

</div>

Or just use `ibegin/iend` from [GitHub - JuliaArrays/EndpointRanges.jl: Julia package for doing arithmetic on endpoints in array indexing](https://github.com/JuliaArrays/EndpointRanges.jl).
