2016-09-08 1 views
1

Je me suis un peu fatigué de définir des fonctions pour différentes permutations de types d'entrée, par exemple.Macros Julia avec plusieurs expressions de retour

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

donc décidé d'essayer ma main à une macro qui renvoie les deux définitions ci-dessus.

J'ai été capable de créer une macro qui permute l'entrée d'argument, mais je n'arrive pas à obtenir plus d'une définition de fonction.

ceci marche:

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 

Je ne peux pas comprendre comment retourner les deux ex et ex_, cependant. Ce fut l'une de mes tentatives:

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 

Qu'est-ce qui se passe avec cette erreur, et comment puis-je retourner deux expressions, ou en quelque sorte d'autre réaliser ce que je suis en train de faire ici?

Editer: Il semble que this est lié, mais je ne vois pas comment je devrais l'adapter à mon cas.

Répondre

2

Dans le bloc quote, vous devez interpoler ex et ex_ comme

return quote 
    $ex 
    $ex_ 
end 
+0

et appliquer également 'esc' comme' $ (esc (ex)) 'et' $ (esc (ex _)) ' –

+0

Cette travaillé. J'aurais juré que j'avais essayé ça. Est-ce nécessaire parce que c'est dans un bloc 'quote'? – DNF