我想更好地理解其中的区别。我在网上找到了很多解释,但它们都倾向于抽象的差异,而不是实际的含义。
Most of my programming experiences has been with CPython (dynamic, interpreted), and Java (static, compiled). However, I understand that there are other kinds of interpreted and compiled languages. Aside from the fact that executable files can be distributed from programs written in compiled languages, are there any advantages/disadvantages to each type? Oftentimes, I hear people arguing that interpreted languages can be used interactively, but I believe that compiled languages can have interactive implementations as well, correct?
从http://www.quora.com/What-is-the-difference-between-compiled-and-interpreted-programming-languages
There is no difference, because “compiled programming language” and
“interpreted programming language” aren’t meaningful concepts. Any
programming language, and I really mean any, can be interpreted or
compiled. Thus, interpretation and compilation are implementation
techniques, not attributes of languages.
Interpretation is a technique whereby another program, the
interpreter, performs operations on behalf of the program being
interpreted in order to run it. If you can imagine reading a program
and doing what it says to do step-by-step, say on a piece of scratch
paper, that’s just what an interpreter does as well. A common reason
to interpret a program is that interpreters are relatively easy to
write. Another reason is that an interpreter can monitor what a
program tries to do as it runs, to enforce a policy, say, for
security.
Compilation is a technique whereby a program written in one language
(the “source language”) is translated into a program in another
language (the “object language”), which hopefully means the same thing
as the original program. While doing the translation, it is common for
the compiler to also try to transform the program in ways that will
make the object program faster (without changing its meaning!). A
common reason to compile a program is that there’s some good way to
run programs in the object language quickly and without the overhead
of interpreting the source language along the way.
You may have guessed, based on the above definitions, that these two
implementation techniques are not mutually exclusive, and may even be
complementary. Traditionally, the object language of a compiler was
machine code or something similar, which refers to any number of
programming languages understood by particular computer CPUs. The
machine code would then run “on the metal” (though one might see, if
one looks closely enough, that the “metal” works a lot like an
interpreter). Today, however, it’s very common to use a compiler to
generate object code that is meant to be interpreted—for example, this
is how Java used to (and sometimes still does) work. There are
compilers that translate other languages to JavaScript, which is then
often run in a web browser, which might interpret the JavaScript, or
compile it a virtual machine or native code. We also have interpreters
for machine code, which can be used to emulate one kind of hardware on
another. Or, one might use a compiler to generate object code that is
then the source code for another compiler, which might even compile
code in memory just in time for it to run, which in turn . . . you get
the idea. There are many ways to combine these concepts.
编译语言是这样一种语言:程序一旦编译,就用目标机器的指令来表达。例如,源代码中的加法“+”操作可以直接转换为机器代码中的“ADD”指令。
解释型语言是指指令不直接由目标机器执行,而是由其他程序(通常用本机语言编写)读取和执行的语言。例如,相同的“+”操作将在运行时被解释器识别,然后调用它自己的“add(a,b)”函数,并使用适当的参数,然后执行机器代码“add”指令。
你可以在编译语言中做你在解释语言中可以做的任何事情,反之亦然——它们都是图灵完备的。然而,这两种方法在实施和使用方面都有优点和缺点。
我将完全概括(纯粹主义者原谅我!),但大致来说,以下是编译语言的优点:
通过直接使用目标计算机的本机代码获得更快的性能
有机会在编译阶段应用相当强大的优化
下面是解释型语言的优点:
更容易实现(编写好的编译器非常困难!!)
不需要运行编译阶段:可以直接“动态”执行代码
是否可以更方便地使用动态语言
注意,字节码编译等现代技术增加了一些额外的复杂性——这里发生的情况是,编译器的目标是一个与底层硬件不同的“虚拟机”。这些虚拟机指令可以在稍后阶段再次编译,以获得本机代码(例如,由Java JVM JIT编译器完成)。
首先,澄清一下,Java不是完全静态编译和以c++的方式链接的。它被编译成字节码,然后由JVM解释。JVM可以对本机机器语言进行即时编译,但不必这样做。
更重要的是:我认为交互性是主要的实际区别。由于所有内容都是解释的,所以您可以截取一小段代码,解析并根据环境的当前状态运行它。因此,如果您已经执行了初始化变量的代码,则可以访问该变量,等等。它真的很适合函数式风格。
然而,解释成本很高,特别是当您有一个包含大量引用和上下文的大型系统时。根据定义,这是一种浪费,因为相同的代码可能必须解释和优化两次(尽管大多数运行时都为此进行了缓存和优化)。不过,您仍然需要支付运行时成本,并且经常需要运行时环境。您也不太可能看到复杂的过程间优化,因为目前它们的性能还没有充分的交互性。
因此,对于不会有太大变化的大型系统,以及某些语言,更有意义的是预编译和预链接所有内容,做所有可以做的优化。最终会得到一个非常精简的运行时,该运行时已经针对目标机器进行了优化。
至于生成可执行文件,恕我直言,这一点关系不大。通常可以从编译语言创建可执行文件。但是您也可以使用解释语言创建可执行文件,只不过解释器和运行时已经打包在可执行文件中,并且对您隐藏了。这意味着您通常仍然需要支付运行时成本(尽管我确信对于某些语言,有方法将所有内容转换为可执行树)。
我不同意所有的语言都可以互动。某些语言,如C语言,与机器和整个链接结构紧密相连,我不确定您是否能够构建一个有意义的完整的交互式版本
从http://www.quora.com/What-is-the-difference-between-compiled-and-interpreted-programming-languages
There is no difference, because “compiled programming language” and
“interpreted programming language” aren’t meaningful concepts. Any
programming language, and I really mean any, can be interpreted or
compiled. Thus, interpretation and compilation are implementation
techniques, not attributes of languages.
Interpretation is a technique whereby another program, the
interpreter, performs operations on behalf of the program being
interpreted in order to run it. If you can imagine reading a program
and doing what it says to do step-by-step, say on a piece of scratch
paper, that’s just what an interpreter does as well. A common reason
to interpret a program is that interpreters are relatively easy to
write. Another reason is that an interpreter can monitor what a
program tries to do as it runs, to enforce a policy, say, for
security.
Compilation is a technique whereby a program written in one language
(the “source language”) is translated into a program in another
language (the “object language”), which hopefully means the same thing
as the original program. While doing the translation, it is common for
the compiler to also try to transform the program in ways that will
make the object program faster (without changing its meaning!). A
common reason to compile a program is that there’s some good way to
run programs in the object language quickly and without the overhead
of interpreting the source language along the way.
You may have guessed, based on the above definitions, that these two
implementation techniques are not mutually exclusive, and may even be
complementary. Traditionally, the object language of a compiler was
machine code or something similar, which refers to any number of
programming languages understood by particular computer CPUs. The
machine code would then run “on the metal” (though one might see, if
one looks closely enough, that the “metal” works a lot like an
interpreter). Today, however, it’s very common to use a compiler to
generate object code that is meant to be interpreted—for example, this
is how Java used to (and sometimes still does) work. There are
compilers that translate other languages to JavaScript, which is then
often run in a web browser, which might interpret the JavaScript, or
compile it a virtual machine or native code. We also have interpreters
for machine code, which can be used to emulate one kind of hardware on
another. Or, one might use a compiler to generate object code that is
then the source code for another compiler, which might even compile
code in memory just in time for it to run, which in turn . . . you get
the idea. There are many ways to combine these concepts.