我已经读过Julia可以访问它运行的代码的AST。这到底是什么意思?是运行时可以访问它,代码本身可以访问它,还是两者都可以?
立足于此:
你在Python中很容易做的事情的示例会是什么?,但你可以在Julia中做到这一点,因为这个? / p>
答案 0 :(得分:15)
Julia与Python之类的语言的区别在于Julia允许您在评估之前拦截代码。宏只是用Julia编写的函数,它允许您在运行之前访问该代码并对其进行操作。此外,不是将代码视为字符串(如"f(x)"
),而是将其作为Julian对象提供(如Expr(:call, :f, :x)
)。
这有很多东西允许在Python中不可能实现。主要是:
这方面的两个很好的例子是正则表达式和printf。这两种都采用某种格式规范并以某种方式解释它。现在,这些可以直接实现为函数,可能如下所示:
match(Regex(".*"), str)
printf("%d", num)
这个问题是每次运行语句时都必须重新解释这些规范 。每次解释器遍历此块时,必须将正则表达式重新编译为状态机,并且格式必须通过迷你解释器运行。另一方面,如果我们将它们实现为宏:
match(r".*", str)
@printf("%d", num)
然后r
和@printf
宏将在编译时拦截代码,并运行各自的解释器然后。正则表达式变成了一个快速状态机,@printf
语句变成了一个简单的println(num)
。在运行时,完成了最少的工作,因此代码非常快速。现在,其他语言能够提供快速正则表达式,例如,通过为它提供特殊语法 - 但它们在Julia中不是特殊的,这意味着开发人员可以在自己的代码中使用相同的技术。 / p>
宏的语言往往具有更强大的嵌入式DSL,因为您可以随意更改语言的语义。例如,代数建模语言JuMP.jl。 Clojure也有一些巧妙的例子,比如它的嵌入式logic programming language。 Mathematica.jl甚至在Julia中嵌入了Mathematica的语义,因此您可以编写真正自然的符号表达式,如@Integrate(log(x), {x,0,2})
。你可以把它伪装成Python中的一个点(SymPy做得很好),但不是干净或有效。
如果这并不能说服你,请考虑有人设法使用宏在纯Julia中实现interactive Julia debugger。在Python中试试。
编辑:其他语言难以解决的另一个很好的例子是Cartestian.jl,它允许您在任意维度的数组中编写泛型算法。
答案 1 :(得分:5)
我对朱莉娅并不熟悉,只是第一次听到你的问题,但这听起来非常像Lisp(事实上朱莉娅似乎是我读过的Lisp的新孙子/方言)它是强大的宏。在运行/编译时访问AST的能力为程序员代码带来了全新的维度:元编程。
有关一些实际用途,请参阅http://docs.julialang.org/en/latest/manual/metaprogramming/,尤其是http://docs.julialang.org/en/latest/manual/metaprogramming/#macros。基本上你可以注射/修改'代码在python / R不可能做同样的地方。
答案 2 :(得分:2)
示例:循环展开,没有任何副本& paste,它使用编译时参数来轻松改变你想要展开循环的次数。
这是Julia元编程的优秀资源:https://en.wikibooks.org/wiki/Introducing_Julia/Metaprogramming