2016-05-14 4 views
2

ライブラリをラップするために自動的に多くのジュリア関数(メタプログラミング)を構築したいと思います。ここでargapとキーワードargsでジュリア関数をメタプログラミングする

は私が生成したい機能です。ここ

function myfunc(a::Array{Float64,1}, b::Array{Float64,1}; x=Int64(1), y=Float64(2)) 
    x + y 
end 

は、私は、このような関数を生成するために使用したい関数のパラメータです。

funcname = :my_func 
args = (:a, :b) 
args_typ = (Array{Float64,1}, Array{Float64,1}) 
kw_args = (:x, :y) 
kw_defval = (1, 2) 
kw_typ = (Int64, Float64) 

私はジュリアマクロと快適に感じることはありませんし、http://docs.julialang.org/en/release-0.4/manual/metaprogramming/はずっと私を助けていません。

また、関数(生成された)コードを表示したいと考えています。

私の最初のアイデア(非常に自動化されていないが)

macro GEN_FUNC(funcname) 
    function $funcname(a, b, x=1, y=2) 
     return x 
    end 
end 

だったが、それはあなたがマクロからの発現を返す必要があり

ERROR: syntax: invalid method name "$funcname" 

答えて

4

を発生させます。コードを式にするには、コードを:(....)またはquote ... endのいずれかで飾ります。また、$は式と文字列に対してのみ有効です。最後に、マクロに衛生上の問題があります。 $funcnameをそのまま維持するには、escが必要です。ここでは、コード

julia> macro GEN_FUNC(funcname) 
      fname=esc(funcname) 
      quote 
       function $fname(a, b, x=1, y=2) 
        return x 
       end 
      end 
     end 

julia> macroexpand(:(@GEN_FUNC testing)) 
quote # none, line 4: 
    function testing(#21#a,#22#b,#23#x=1,#24#y=2) # none, line 5: 
     return #23#x 
    end 
end 

更新修正されています。私はからこれを行う方法を学びました

julia> f_body=:(x+y) 
:(x + y) 

julia> f_parameters=Expr(:parameters, Expr(:kw,:x,Int64(1)), Expr(:kw,:y,Float64(2))) 
:($(Expr(:parameters, :(x=1), :(y=2.0)))) 

julia> f_call=Expr(:call,:myfunc,f_parameters,:(a::Array{Float64,1}),:(b::Array{Float64,1})) 
:(myfunc(a::Array{Float64,1},b::Array{Float64,1}; x=1,y=2.0)) 

julia> f_declare=Expr(:function,f_call,f_body) 
:(function myfunc(a::Array{Float64,1},b::Array{Float64,1}; x=1,y=2.0) 
     x + y 
    end) 

julia> eval(f_declare) 
myfunc (generic function with 1 method) 

julia> myfunc(2,3) 
ERROR: MethodError: `myfunc` has no method matching myfunc(::Int64, ::Int64) 

julia> myfunc([2.],[3.]) 
3.0 

julia> myfunc([2.],[3.];x=4,y=8.) 
12.0 
+0

自動的に引数を生成する方法は? –

+0

更新された回答を見てください。 –

+0

私はまだタプルから 'f_parameters'と' f_call'をビルドするという問題に直面しています。どんな助けも素晴らしいでしょう。 –

1

:ここmyfuncを手動で(私はそれquote ... endと表現作られ、それから騙さヒント)を構築することができる方法でありますMITのSteven G. Johnsonによる、素敵なDecFP.jlパッケージ(https://github.com/stevengj/DecFP.jl)へのソースコードの読み込み。

@evalマクロを持つ単純なループを使用して、Cライブラリのすべてのラッパーを生成します。

関連する問題