在此基础上:
1. 这是Julia相对于其他动态语言,特别是Python的关键区别吗? 2. 能够访问AST的实际好处是什么? 3. 由于这个原因,有没有一个好的例子,是你不能轻松地在Python中完成,但是在Julia中可以做到的?
与Python等语言不同的是,Julia允许你在代码被评估之前截取它。宏只是用Julia编写的函数,它允许你访问该代码并在运行之前操纵它。此外,它不像“"f(x)"
”一样将代码作为字符串处理,而是提供作为Julia对象(如Expr(:call, :f, :x)
)。
这种方法有很多好处,在Python中根本无法实现。其中主要的优点是:
正则表达式和printf就是两个很好的例子。它们都需要格式说明,并以某种方式进行解释。现在,这些可以相当简单地实现为函数,看起来可能像这样:
match(Regex(".*"), str)
printf("%d", num)
这个问题在于每次运行语句时必须重新解释这些规范。每当解释器遍历此块时,正则表达式必须被重新编译成状态机,并且格式必须通过一个微型解释器运行。另一方面,如果我们将它们实现为宏:
match(r".*", str)
@printf("%d", num)
那么,r
和@printf
宏将在编译时拦截代码,并运行它们各自的解释器然后。正则表达式变成了一个快速状态机,@printf
语句变成了一个简单的println(num)
。在运行时只需完成最少的工作,因此代码非常快。现在,其他语言也能提供快速的正则表达式,例如,通过为其提供特殊的语法——但是Julia没有对其进行特殊处理,这意味着开发人员可以在自己的代码中使用相同的技术。
有宏的语言往往具有更强大的嵌入式DSL,因为您可以随意更改语言的语义。例如,代数建模语言JuMP.jl。Clojure也有一些很棒的例子,比如嵌入式的逻辑编程语言。甚至还有Mathematica.jl,它将Mathematica的语义嵌入到Julia中,这样您就可以编写非常自然的符号表达式,例如@Integrate(log(x), {x,0,2})
。在Python中,您可以通过SymPy实现类似的功能,但不如Julia干净和高效。
如果这还不能说服您,请考虑有人使用宏在纯Julia中实现了一个交互式Julia调试器。在Python中试试看吧。
编辑:另一个很好的例子是Cartestian.jl,它允许您在任意维度的数组上编写通用算法。
例子:循环展开而不需要复制和粘贴,它带有一个编译时参数,可以轻松地改变您想展开循环的数量。
这是一份关于Julia元编程的优秀资源:https://en.wikibooks.org/wiki/Introducing_Julia/Metaprogramming
ast.parse
一些源代码并在以后执行它。 - kojiro