macrosjuliamultiple-return-values

Julia macros with multiple return expressions


I got a bit tired of defining functions for different permutations of input types, e.g.

f(x::MyType1, y::MyType2) = x.data + y.data
f(y::MyType2, x::MyType1) = x.data + y.data

so decided to try my hand at a macro that returns both of the above definitions.

I was able to make a macro that switches the argument input, but I can not get it to return more than one function definition.

So this works:

julia> macro argrev(ex)
          if (ex.head == :(=)) && (ex.args[1].head == :call)
              ex_ = copy(ex)
              args = ex_.args[1].args
              args[2:3] = args[[3, 2]]
              return ex_
          end
          return ex
       end
@argrev (macro with 1 method)

julia> @argrev f(x::Int, y::Float64) = x + y
f (generic function with 1 method)

julia> f(2, 3.5)
MethodError: no method matching f(::Int64, ::Float64)

julia> f(3.5, 2)
5.5

I cannot figure out how to return both ex and ex_, though. This was one of my attempts:

julia> macro argrev1(ex)
           if (ex.head == :(=)) && (ex.args[1].head == :call)
               ex_ = copy(ex)
               args = ex_.args[1].args
               args[2:3] = args[[3, 2]]
               return quote
                   ex
                   ex_
               end
           else
               return ex
           end
       end
@argrev1 (macro with 1 method)

julia> @argrev1 f(x::Int, y::Float64) = x + y
UndefVarError: ex_ not defined

What's going on with this error, and how can I return two expressions, or somehow else achieve what I'm trying to do here?

Edit: It seems like this is related, but I don't quite see how I should adapt it to my case.


Solution

  • In quote block, you need to interpolate ex and ex_ like

     return quote
        $ex
        $ex_
     end