【问题标题】:Benefits of accessing the Abstract Syntaxt Tree (AST) . How does Julia exploit it?访问抽象语法树 (AST) 的好处。 Julia 如何利用它?
【发布时间】:2014-04-02 15:15:37
【问题描述】:

我读到 Julia 可以访问它运行的代码的 AST。这到底是什么意思?是运行时可以访问它,代码本身可以访问它,还是两者兼而有之?

以此为基础:

  1. 这是 Julia 与其他动态语言(尤其是 Python)的主要区别吗?
  2. 能够访问 AST 有哪些实际好处

什么是一个很好的示例,说明您在 Python 中无法轻松完成,但您可以因此在 Julia 中完成?

【问题讨论】:

  • Python code objects 没有对其 AST 的直接反向编译访问权限,但 Python AST objects 可以编译为代码对象,因此您始终可以 ast.parse 某些源代码并稍后执行。

标签: python abstract-syntax-tree julia


【解决方案1】:

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 中没有特殊情况,这意味着开发人员可以在自己的代码中使用相同的技术。

你可以为几乎任何东西制作迷你编译器

带有宏的语言往往具有更强大的嵌入式 DSL,因为您可以随意更改语言的语义。例如,代数建模语言JuMP.jl。 Clojure 也有一些很好的例子,比如它嵌入的logic programming languageMathematica.jl 甚至在 Julia 中嵌入了 Mathematica 的语义,这样你就可以编写像 @Integrate(log(x), {x,0,2}) 这样的非常自然的符号表达式。您可以在 Python 中将其伪装成某种程度(SymPy 做得很好),但没有那么干净或高效。

如果这不能说服您,请考虑有人设法在纯 Julia 中使用宏实现了 interactive Julia debugger。在 Python 中尝试一下。

编辑:另一个在其他语言中比较困难的例子是Cartestian.jl,它可以让您编写跨任意维数数组的通用算法。

【讨论】:

    【解决方案2】:

    我对 Julia 不熟悉,只是第一次听说你的问题,但这听起来很像 Lisp(实际上 Julia 似乎是我正在阅读的 Lisp 的新孙子/方言),而且它是强大的宏。在运行/编译时访问 AST 的能力为程序员代码带来了一个全新的维度:元编程。

    请参阅http://docs.julialang.org/en/latest/manual/metaprogramming/,尤其是http://docs.julialang.org/en/latest/manual/metaprogramming/#macros,了解一些实际用途。基本上,您可以在 python/R 无法执行相同操作的地方“注入/修改”代码。

    【讨论】:

      【解决方案3】:

      示例:不进行任何复制和粘贴的循环展开,它采用编译时参数来轻松改变您想要展开循环的程度。

      这里有一个关于 Julia 元编程的优秀资源:https://en.wikibooks.org/wiki/Introducing_Julia/Metaprogramming

      【讨论】:

        猜你喜欢
        • 2015-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-10
        相关资源
        最近更新 更多