是否总是解释动态语言?


18

查看最多(如果不是全部)动态语言(例如Python,PHP,Perl和Ruby),它们都将被解释。如果我错了纠正我。动态语言有没有经过编译阶段的示例?动态语言与解释语言是否相同?


4
定义动态语言,是否动态输入?
— 本杰明·

3
Objective-C具有许多“动态”特性。
— 爱德华·斯特兰奇

4
@Job,使用Lisp可以做到数十年。它既可以编译也可以动态输入。因此,在编译和解释之间从来没有一个确切的界限。
— SK-logic

2
@Darien您也可以在运行时进行编译,然后再执行代码。严格来说,这不是解释。
— xmm0 2011年

3
@Darien Nothing不能阻止编译器将符号表信息存储在已编译的二进制文件中并生成代码以在运行时对其进行访问。的确,有些语言比解释更适合于解释,但要点是,有可能为该语言提供编译器。要注意的另一重要事项是,有些人认为编译器必须生成某种机器代码。实际上,有些编译器可以简单地跨两种语言(甚至是相同的语言,例如某些Javascript缩小器)执行源代码级转换。
— xmm0 2011年

Answers:


33

查看最多(如果不是全部)动态语言(例如,Python,PHP,Perl和Ruby),它们都可以被解释。

不对。您可以编译Python源代码。那是一个存在的证明。

有用于静态类型语言的解释器和用于动态类型语言的编译器。这两个概念是正交的。

旁注:通常,一种语言就是:一种语言,具有一组表达语义的语法结构。如果您在白板上编写Python,它仍称为Python!它的实施,可以是翻译或编译器。静态类型或动态类型(两者的混合体)是语言的属性,而通过解释或编译执行程序是实现的属性。


19
缩进必须在白板上匹配多少精度才能使Python在语法上有效?;)
— edA-qa mort-ora-y

1
您不能编译Python。PYC仅加速模块的负载。py2exe只是将解释器与源文件嵌入到exe中。
— 本杰明·

8
@Ubiquité:.pyc文件是字节码。Python源代码经过解析,优化和编译以创建它们。字节码指令是相对高级的,并且最流行的实现是普通的解释器(相比之下,请看PyPy,它在运行时通过JIT将字节码编译为非常聪明的机器代码),但是Python的编译过程并不比Java或Java少。 C#。仅当“编译”仅限于本机提前编译时,Python才“未编译” ,但是没有人对此发表任何意见,并且通常它可以引用任何语言到语言的转换。

4
@Ubiquité:是的,这是正确的,但站在没有关系你声称“你不能编译的Python”或是否有可能编译Python的。首先,您要混合Python和CPython,而后者是前者的实现,所以也是PyPy。
— phant0m 2011年

2
@ClemC语言的所有属性都内置在编译器或解释器中,否则解释器或编译器就是另一种语言的东西。
— Pieter B

15

Common Lisp是动态(强烈)键入的,通常是编译的。

由于这种动态性是在运行时实现的,因此可以在源代码中使用一些指令,以确保编译器符号仅包含某种值,以便编译器可以优化生成的代码并提高性能。


12

C#4.0支持动态类型(后期绑定),并且已对其进行编译。



3

否-编译动态语言当然是可能的。

甚至有些动态语言总是通过设计编译的(例如Clojure)。

然而,这个问题涉及到一个重要的相关点:尽管可以编译动态语言,但通常情况下,无法将动态语言编译成与静态类型的语言一样有效的代码。这是因为动态语言中的某些固有功能需要进行运行时检查,而这在静态编译的语言中是不必要的。

这样的一个例子:允许对对象进行运行时修补的语言(例如Ruby)通常在您在对象上调用方法时都需要检查该对象(使用哈希表查找或类似方法)。即使已编译,编译器也将不得不在运行时生成代码以进行方法查找。在某种程度上,此方法查找与解释器必须执行的操作并无不同。

与Java之类的语言中的方法调用相比,这增加了相当大的开销,在Java中,正确的方法可以由编译器根据类定义静态确定,并可以用本机代码简化为简单的函数调用。

我相信,这种影响比其他任何因素都更能导致动态语言的性能平均比静态编译的语言慢。从有缺陷的基准中可以看到,排名靠后的是静态类型的语言(C,Java,Fortran等),而动态语言(Perl,Python,Ruby,PHP等)的运行速度最快。


2

从前,BASIC被解释了。BASIC的某些变体具有动态类型。您也可以为他们获得编译器。

(这可以追溯到10万张软盘驱动器的时代,当时恐龙仍在地球上漫游,并以毫无戒心的软件开发人员吃早餐。)


...但仅当他们使用GOTO时。(如果他们使用BASIC进行开发,那当然很常见。AHA!这解释了!)
— Mason Wheeler

BASIC在设计时就是一种编译语言。
— AProgrammer

2

不同的Smalltalk实现对此处理方式有所不同,但是其中一些实现可编译为在高性能VM上运行的字节码。


2

实际上,大多数所谓的“解释”语言都经过/允许及时编译以使其运行更快。并且其中一些必须先编译为字节码,然后才能运行它们。

实际上,动态和解释虽然有关联,但完全是两个不同的想法。曾经感到动态打字的原因是使他们的工作变得更加轻松和快捷,他们不介意代码会慢一些但可移植。


1

Chrome,IE9和Firefox 3.1+都将JavaScript编译为本机二进制文件,并且JavaScript是动态键入的。

我认为历史上倾向于解释动态语言的原因是因为动态类型和解释(或更具体地说,缺少编译)都倾向于对脚本语言和脚本任务有用。

对于用这些语言编写的程序种类,性能也不是(不是)要关注的问题,因此,动态键入和解释的开销也不会像使用语言那样大重视绩效。


1

通常,Python已编译。公认编译为字节代码,然后将其解释。

Perl以类似的方式工作。

Common Lisp通常将编译为本地或字节代码之一。这在实现之间有所不同(在某种程度上,在实现内,取决于各种优化设置)。


-5

是。所有动态语言都是解释性语言(但解释性语言可能不是动态的)。

原因很简单:如果它是动态的,则需要一个解释器来在二进制编译级别执行动态性。

例如 :当我们将数据放入PHP变量中,然后再放入另一个不同类型的数据时,我们的程序无法编译为二进制代码,因为每种类型都有自己的二进制表示格式;解释器以动态方式管理二进制级别的移位


2
错误。可以编译动态语言(有时非常有效,例如,使用JIT和自适应编译技术)
— Basile Starynkevitch

“大致上,JIT编译结合了已编译代码的速度和解释的灵活性以及解释器的开销……” en.wikipedia.org/wiki/Just-in-time_compilation您的程序无法编译:它是由为您提供的口译服务
— ClearMind


当然。您的链接提到:“ Self的一个功能是,它基于与早期Smalltalk系统使用的虚拟机系统相同的类型。也就是说,程序不是独立的实体,而是像C这样的语言,但是需要它们整个内存环境才能运行。” 非独立=未二进制编译需要虚拟机执行二进制编译
— ClearMind

1
您对编译器的定义过于严格。并非每个编译器都会生成二进制可执行文件。对于最近的反例,请研究SBCL的实现。阅读最新的《Dragon Book and Lisp in Small Pieces
— Basile Starynkevitch》,2008年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.