如何使用函数args进行元编程?

Aar*_*onP 1 scope metaprogramming julia

这是我第二天学习和实验朱莉娅.虽然我仔细阅读了有关元编程的文献记录(但可能不够仔细)和几个类似的线程.我仍然无法弄清楚如何在函数中使用它.我试着让以下函数更灵活地模拟一些数据:

using Distributions
function gendata(N,NLATENT,NITEMS)
  latent = repeat(rand(Normal(6,2),N,NLATENT), inner=(1,NITEMS))
  errors = rand(Normal(0,1),N,NLATENT*NITEMS)
  x = latent+errors
end
Run Code Online (Sandbox Code Playgroud)

通过做这个:

using Distributions
function gendata(N,NLATENT,NITEMS,LATENT_DIST="Normal(0,1)",ERRORS_DIST="Normal(0,1)")
  to_eval_latent = parse("latent = repeat(rand($LATENT_DIST,N,NLATENT), inner=(1,NITEMS))")
  eval(to_eval_latent)
  to_eval_errors = parse("error = rand($ERRORS_DIST,N,NLATENT*NITEMS)")
  eval(to_eval_errors)
  x = latent+errors
end
Run Code Online (Sandbox Code Playgroud)

但由于eval不适用于本地范围,因此不起作用.我可以做些什么来解决这个问题呢?

最初的功能,似乎并不那么快,我是否在性能方面犯了重大错误?

我真的很喜欢任何推荐.提前致谢.

Isa*_*ton 5

不需要在那里使用eval,您可以通过将分发类型作为关键字args(或使用默认值命名的args)传递来保持相同的灵活性.解析和评估"字符串式"参数通常会使优化失败,应该避免.

function gendata(N,NLATENT,NITEMS;  LATENT_DIST=Normal(0,1),ERRORS_DIST=Normal(0,1))
         latent = repeat(rand(LATENT_DIST,N,NLATENT), inner=(1,NITEMS))
         errors = rand(ERRORS_DIST,N,NLATENT*NITEMS)
         x = latent+errors
end


julia> gendata(10,2,3, LATENT_DIST=Pareto(.3))
...


julia> gendata(10,2,3, ERRORS_DIST=Gamma(.6))
...
Run Code Online (Sandbox Code Playgroud)

等等