I'm working (in 3.7) on a function that takes two functions f and g as 
inputs, merges all non-conflicting methods of f and g into one function h, 
and returns h. I'm trying to use macros to generate the signatures of each 
method for h:

macro argsgen(typle, n::Int64)
    y = eval(:($typle))
    xn = symbol("x$n")
    return :( $xn :: $(y[n]) )
end

macro repper(typle, n::Int64)
    ex = "@argsgen($typle, 1)"
    for i in 2:n
        ex = string(ex, ", @argsgen($typle, $n)")
    end

    return parse(ex)
end

So, if f has a method with signature (x::Int64), then I can feed the 
1-tuple '(Int64,)' to @argsgen, which generates the proper signature: 

julia> ex1 = macroexpand( :(@argsgen((Int64,), 1) ))
:(x1::Int64)

and I can thereby define a method for h:


julia> h(@argsgen((Int64,), 1)) = x1 + 1
foobar (generic function with 1 method)

julia> h(1)
2

The problem is when I try to do this for a signature of more than one 
argument, say (Int64, Int64). Above I've tried implementing a macro that 
generates an expression of repeated '@argsgen' calls with the appropriate 
second argument:

ex = macroexpand( :( @repper (Int64, Int64) 2 ) )
:((x1::Int64,x2::Int64))

which doesn't quite work when I attempt to use it for a signature:

julia> h(@repper (Int64, Int64) 2) = x1 + x2
ERROR: syntax: "(x1::Int64,x2::Int64)" is not a valid function argument name

How can I get @repper to return an expression that isn't a tuple, but also 
has two @argsgen calls separated by a comma? I've tried a couple of other 
ways of doing this, but each expression wants to be returned as a tuple. 
And I can't find out how to make the tuple splat in such a way that works 
as a signature for h. Any thoughts? (Also, I imagine the tupocalypse will 
break this, but I can deal with that later.) 

Thank you all!
David

Reply via email to