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> 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…
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:
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.
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.