Вызов функций julia с аргументами ключевых слов с использованием макроса - PullRequest
0 голосов
/ 04 октября 2018

Я пытаюсь написать макрос, который вызывает функции с аргументами ключевых слов (для использования в JuMP NL выражений и отображений. Эти функции являются просто функциями для доступа к базе данных. Поэтому они не представляют математическую операцию).

Минимальный пример:

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

Надеюсь, вы поняли мою идею, я очень ценю вашу помощь!

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Для более низких версий Джулии это может быть решено как:

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

Примечание: До сих пор я не смог добавить экранирование ...

0 голосов
/ 04 октября 2018

Мне непонятно, зачем вам нужен макрос для этого, но в любом случае.

  1. Синтаксис Julia для

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

    равен

    function foo1(; a::Int=1)
        a
    end
    
  2. Не вызывать eval из макроса, макросы принимают выражение в качестве входных данных и должны возвращать выражение.

  3. Пользовательский ввод должен быть escaped, см. https://docs.julialang.org/en/v1/manual/metaprogramming/#Hygiene-1

Вот прототип реализации:

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
...