使用宏调用带有关键字参数的julia函数

使用宏调用带有关键字参数的julia函数,julia,metaprogramming,Julia,Metaprogramming,我正在尝试编写一个宏,它使用关键字参数调用函数(用于跳转表达式和映射中。这些函数只是用于访问数据库的函数。因此它们不表示数学运算) 最简单的例子: function foo1(; int::a=1) a end function foo2(; int::a=1, int::b=2) b end macro callfunc(f, keywordargs) #function should be called here using symbol #return

我正在尝试编写一个宏,它使用关键字参数调用函数(用于跳转表达式和映射中。这些函数只是用于访问数据库的函数。因此它们不表示数学运算)

最简单的例子:

function foo1(; int::a=1)
    a
end

function foo2(; int::a=1, int::b=2)
    b
end

macro callfunc(f, keywordargs)
    #function should be called here using symbol
    #return values of f should be returned by macro callfunc
    ex= :($(that)(;$(keywordargs)...)) #this syntax is not correct for sure
    return eval(ex) 
end

@callfunc(foo1, (a=1))
#should return 1

@callfunc(foo2, (a=1, b=2))
#should return 2

我希望你明白我的想法,我真的很感谢你的帮助

我不清楚为什么需要一个宏,但无论如何

  • 的Julia语法

    function foo1(; int::a=1)
        a
    end
    

  • 不要从宏调用
    eval
    ,宏将表达式作为输入,并应返回表达式

  • 用户输入需要
    esc
    aped,请参阅
  • 以下是一个原型实现:

    macro callfunc(f, kwargs...)
        x = [esc(a) for a in kwargs]
        return :($(f)(; $(x...)))
    end
    
    使用示例用法:

    julia> foo1(; a::Int = 1) = a;
    
    julia> foo2(; a::Int = 1, b::Int = 2) = b;
    
    julia> @callfunc foo1 a = 5
    5
    
    julia> @callfunc foo2 a = 5 b = 6
    6
    

    对于较低版本,可通过以下方式解决:

    macro NL(f, kwargs...)
        #julia 1.0 code:
        # x = [esc(a) for a in kwargs]
        # return :($(f)(; $(x...)))
    
        #for julia 0.6.x this needs to be a dict (symbol => value)
        x_dict = Dict(a.args[1] => a.args[2] for a in kwargs)
        #todo: add escaping!
        return :($(f)(; $(x_dict...)))
    end
    

    注意:到目前为止,我无法添加转义…

    这在Julia 1.0中非常有效。但是我面临着与Julia 0.6.4的兼容性问题。Julia 0.6x中会是什么样子?
    macro NL(f, kwargs...)
        #julia 1.0 code:
        # x = [esc(a) for a in kwargs]
        # return :($(f)(; $(x...)))
    
        #for julia 0.6.x this needs to be a dict (symbol => value)
        x_dict = Dict(a.args[1] => a.args[2] for a in kwargs)
        #todo: add escaping!
        return :($(f)(; $(x_dict...)))
    end