访问抽象语法树(AST)的好处。Julia语言如何利用它?

7
我读到Julia可以访问它运行的代码的AST。这究竟意味着什么?是运行时可以访问,代码本身可以访问,还是两者都可以?
在此基础上:
1. 这是Julia相对于其他动态语言,特别是Python的关键区别吗? 2. 能够访问AST的实际好处是什么? 3. 由于这个原因,有没有一个好的例子,是你不能轻松地在Python中完成,但是在Julia中可以做到的?

2
Python的code objects没有直接反编译访问它们的AST,但是Python AST objects可以被编译成code objects,所以你总是可以ast.parse一些源代码并在以后执行它。 - kojiro
3个回答

16

与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,它允许您在任意维度的数组上编写通用算法。


5
我对Julia不熟悉,直到看到你的问题才第一次听说它,但这听起来非常像Lisp(实际上,根据我所读的,Julia似乎是Lisp的新后代/方言),拥有强大的宏。在运行/编译时访问AST的能力为程序员的代码带来了全新的维度:元编程。
请参见http://docs.julialang.org/en/latest/manual/metaprogramming/,尤其是http://docs.julialang.org/en/latest/manual/metaprogramming/#macros,了解一些实际用途。基本上,您可以在Python/R无法执行相同操作的位置“注入/修改”代码。

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接