Julia:使用许多不同但相关的算法选择来构建代码 [英] Julia: Structuring code with many different but related algorithm choices
问题描述
我正在寻找一种优雅的方式来重新排列我的代码.对于开发求解器,您可以有许多具有相同设置的不同选项.例如,在高层次上,代码如下所示:
I am looking for an elegant way to re-arrange my code. For developing solvers, what happens is you can have a lot of different options which have the same setup. For example, at a high level the code looks something like this:
function solver()
# Start by assigning a bunch of variables, preprocessing, etc.
...
# Choose and execute solve
if alg==1 doAlgorithm1()
elseif alg==2 doAlgorithm2()
elseif alg==3 doAlgorithm3()
end
# Postprocess and return
...
end
以前,当我快速制作原型时,我将求解器算法放在代码中.但是,随着我对越来越多的算法进行标记,这变得很混乱(尤其是当有些算法有数百行代码时),因此我想将这些调用作为一个单独的函数.但是,我希望它们本质上与将代码块放在那里相同:访问相同的范围,产生副作用等.
Previously when I quickly prototypes I put the solver algorithms right in the code. However, as I am tagging on more and more algorithms this is becoming messy (especially when some are hundreds of lines of code) and so I want to put those calls as a separate function. However, I want them to essentially be the same thing as putting the block of code there: access the same scope, have side effects, etc.
我考虑过为此使用宏,但由于它们在全局范围内进行评估,因此似乎是错误的解决方案.嵌套函数似乎是可行的,但我必须在求解器的顶部定义它们(我的目的是不这样做以保持高级算法的可读性)并且在嵌套函数中定义嵌套函数的范围存在问题(对于仅在某些算法中重复的部分!).我可以将其定义为另一个函数,而无需尝试保持相同的范围,但是如果使用长尾参数(每个算法具有相同的参数!)
I thought about using a macro for this, but since they eval at the global scope it seemed like the wrong solution. Nested functions seem like they might be doable but I have to define them at the top of the solver (and my intention was to not do that to keep the high level algorithm readable) and there are issues with scoping a nested function within a nested function (for parts which repeat in only some of the algorithms!). I could just define this as another function without trying to keep the same scope but then it would be ugly with a long trail parameters (with each algorithm having the same parameters!)
组织这种代码的好方法是什么?对于这个问题,是否有更儒略的方法?
What is a good way to organize this kind of code? Is there a more Julian approach to this problem?
推荐答案
我不确定这是否比使用状态对象更好,但您可以使用宏来实现您想要的:
I am not sure if this is a better approach than using a state object, but you can use macros to achieve what you want:
macro f()
quote
b = 5
x = a * b
x # the value of a block is equal to its last statement
end
end
function foo()
a = 2
b = 3
x = @f()
x, b # (10,3)
end
请注意,Julia
会自动使用唯一名称替换宏中的 b
和 x
以避免副作用.如果想有副作用,可以使用以下方法:
Note that Julia
automatically replaces b
and x
within the macro with a unique name to avoid side effects. If you want to have side effects, you can use the following:
macro g()
esc(quote
b = 5
x = a * b
end)
end
function bar()
a = 2
b = 3
@g()
x, b # (10,5)
end
这相当于将@g()
替换为g()定义中
quote
和end
之间的代码代码>.还可以定义一个方便的小宏:
This is equivalent to replacing @g()
with the code between quote
and end
from the definition of g
. One can also define a small convenience macro:
macro def(name, definition)
return quote
macro $(esc(name))()
esc($(Expr(:quote, definition)))
end
end
end
这样,g
就可以定义为
@def g begin
b = 5
x = a*b
end
这篇关于Julia:使用许多不同但相关的算法选择来构建代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!