可以为动态语言创建编译器而不会失去动态特性吗?

时间:2013-09-07 12:21:47

标签: python ruby compiler-construction compilation dynamic-languages

是否存在一些原因使得Python或Ruby等动态语言无法在不丢失任何动态特征的情况下编译而不是被解释?

当然,对该假设编译器的一个要求是这些语言不会失去他的任何特性,如元编程,扩展对象,添加代码或在运行时修改类型系统。

总结一下,有可能创建一个Ruby或Python编译器,而不会失去他作为动态编程语言的任何特性吗?

2 个答案:

答案 0 :(得分:2)

是的,绝对可以为动态语言创建编译器。在野外有无数动态语言编译器的例子:

  • CPython是Python编程语言的一个实现,它有一个Python编译器。
  • PyPy是Python编程语言的一个实现,它有一个Python编译器。
  • Jython是Python编程语言的一个实现,它有一个Python编译器。
  • IronPython是Python编程语言的一个实现,它有一个Python编译器。
  • Pynie是Python编程语言的一个实现,它有一个Python编译器。
  • YARV是Ruby编程语言的一个实现,它有一个Ruby编译器。
  • Rubinius是Ruby编程语言的一个实现,它有一个Ruby编译器。
  • MacRuby是Ruby编程语言的一个实现,它有一个Ruby编译器。
  • JRuby是Ruby编程语言的一个实现,它有一个Ruby编译器。
  • IronRuby是Ruby编程语言的一个实现,它有一个Ruby编译器。
  • MagLev是Ruby编程语言的一个实现,它有一个Ruby编译器。
  • Quercus是PHP编程语言的一个实现,它有一个PHP编译器。
  • P8是PHP编程语言的一个实现,它有一个PHP编译器。
  • V8是ECMAScript编程语言的一种实现,它具有ECMAScript编译器。

通常,每种语言都可以由编译器实现,每种语言都可以由解释器实现。也可以自动从解释器派生编译器,反之亦然。

大多数现代语言实现都使用解释和编译,有时甚至是几个编译器。以Rubinius为例:首先将Ruby代码编译为Rubinius字节码。然后由Rubinius VM解释Rubinius字节码。已经多次解释的代码然后被编译为Rubinius Compiler IR,然后将其编译为LLVM IR,然后将其编译为“本机代码”(无论是什么)。所以,Rubinius有一个翻译和三个编译器。

V8是一个不同的例子。它实际上有 no 解释器,但是有两个不同的编译器:一个非常快速,非常高效的内存编译器,它可以生成未经优化的,有点慢的代码。已经多次运行的代码被丢弃,然后使用第二个编译器再次编译,这会产生积极优化的代码,但在编译期间需要更多时间并使用更多内存。

但是,最终,无法在没有解释器的情况下运行代码。编译器无法运行代码。编译器将程序从一种语言翻译成另一种语言。而已。你可以翻译你想要的所有内容,最后,某些东西必须运行代码,而那东西是一个解释器。它可以用软件或硅片实现,但它仍然是一个解释器。

答案 1 :(得分:1)

我只是假设“编译”你的意思是“编译为原生机器代码”并留给其他人来挑战这个非常狭窄的定义。答案是响亮的。事实上,人们现在正在这样做:

  • Nuitka
  • Cython(实际上不是Python,但非常接近,可以支持完整的Python)。
  • 各种“冻结”工具,虽然从技术上讲,它们只将字节码和字节码解释器打包成一个二进制文件。

但是,这样的编译器不能执行很多(我会说实际上是零)优化,所以生成的代码基本上等同于一个简单的解释器会做的事情,你只能节省解释开销(而且你会丢失一些解释器的优良特性,包括紧凑的代码和更快的周转时间)。换句话说:Dynamic, correct, fast - choose two(完全披露:接受的答案是我的)。