Issue with macros and `x[end]`


#1

Macros understand getindex syntax for numbers but not end word and throw error.

julia> @which xdots[end]
ERROR: UndefVarError: end not defined
Stacktrace:
 [1] top-level scope at none:0

julia> @which xdots[1]
getindex(A::Array, i1::Int64) in Base at array.jl:731

#2

No, this is an issue of the @which macro:

julia> macro m(x)
       @show x
       x
       end                                                                                                                                                              
@m (macro with 1 method)                                                                                                                                                

julia> x = [1]                                                                                                                                                          
1-element Array{Int64,1}:                                                                                                                                               
 1                                                                                                                                                                      

julia> @m x[end]                                                                                                                                                        
x = :(x[end])                                                                                                                                                           
1                                                                                                                                                                       

#3

However many other macros (@code_*, @less, @edit) in Base have the same issue.


#4

Yes, looking at the macroexpand:

julia> @macroexpand @which x[end]
:((InteractiveUtils.which)(getindex, (Base.typesof)(x, end)))

julia> @macroexpand @which x[1]
:((InteractiveUtils.which)(getindex, (Base.typesof)(x, 1)))

so, what should be done is check for an end and if found instead expand to

InteractiveUtils.which(getindex, (Base.typesof)(x, lastindex(x))) 

However, that might be more trouble than it is worth.


#5

Lowering code already does this though, so the right way to fix this may be to do lowering first and then do the method lookup on whatever it gets lowered to. Could someone file an issue about this bug?


#6

Yeah, that’s how it used to work, and in this case it might work, but lowering does lots of other things and often will expand out to more than one line of code. So we’ve settled on just implementing a small subset of the “helpful” lowering manually within the macro itself. I believe we do have Julia code somewhere in Base that does this part of the lowering transform, so we could probably easily perform it here, too.


#7

I submitted an issue at https://github.com/JuliaLang/julia/issues/29177 .


#8

Why don’t you add your first example to the issue, saves people some clicks.


#9

My bad. I updated with examples and your comment.