Square bracket setindex! in macro argument

question

#1

Hi all,

I’m using macros to generate functions with repetitive structure (in this case, modifying one or more vectors in place). The following works well:

macro mymacro(ex)
    return quote
        for i in eachindex(Y)
            y = Y[i]
            $ex
        end
    end
end

myfunction!(X, Y, a) = @mymacro(setindex!(X, a + y, i))

But ideally, I would use square bracket syntax instead of explicitly calling setindex!:

myfunction2!(X, Y, a) = @mymacro(X[i] = a + y)

Unfortunately, in that case expanding the macro throws the following error:

 ERROR: LoadError: syntax: unhandled expr (kw (call getindex X i) (call + a #96#y))
 in eval_user_input(::Any, ::Base.REPL.REPLBackend) at ./REPL.jl:64
 in macro expansion at ./REPL.jl:95 [inlined]
 in (::Base.REPL.##3#4{Base.REPL.REPLBackend})() at ./event.jl:68

So it seems X[i] is being parsed into a getindex instead of a setindex!. Is this a fundamental macro / parsing limitation or is there something I can do to avoid it? Or is this a misdiagnosis of the problem?

Thanks,
Gord


#2

This is caused by @m(a = b) parsing as keyword argument. IIUC @m a = b should be parsed as = instead. You can do the transformation by tranlating Expr(:kw) into Expr(:(=)) with the same arguments.

Also note that you might want to properly escape the expressions.


#3

Ah, thanks.

myfunction3!(X, Y, a) = @mymacro X[i] = a + y

works as expected.