与静态类型语言相比,动态类型语言的优点和局限性是什么?

另见:动态语言的爱是什么(一个更具争议性的话题…)


当前回答

摘自Artima的《Typing: Strong vs. Weak, Static vs. Dynamic》文章:

强类型可以防止在不匹配的类型之间混合操作。为了混合类型,必须使用显式转换 弱类型意味着可以在没有显式转换的情况下混合类型

在Pascal Costanza的论文《动态与静态类型——基于模式的分析》(PDF)中,他声称在某些情况下,静态类型比动态类型更容易出错。一些静态类型语言强迫你手动模拟动态类型,以便做“正确的事情”。Lambda the Ultimate讨论过这个问题。

其他回答

解释器推断类型和类型转换的能力使开发时间更快,但它也可能引发运行时失败,这是在静态类型语言中无法得到的,因为在编译时就可以捕捉到。但是哪一个更好(或者即使这是真的)最近在社区里被热议(而且已经持续了很长一段时间)。

关于这个问题,Erik Meijer和Peter Drayton在微软的《可能时静态类型,需要时动态类型:编程语言冷战的结束》中给出了一个很好的解释:

Advocates of static typing argue that the advantages of static typing include earlier detection of programming mistakes (e.g. preventing adding an integer to a boolean), better documentation in the form of type signatures (e.g. incorporating number and types of arguments when resolving names), more opportunities for compiler optimizations (e.g. replacing virtual calls by direct calls when the exact type of the receiver is known statically), increased runtime efficiency (e.g. not all values need to carry a dynamic type), and a better design time developer experience (e.g. knowing the type of the receiver, the IDE can present a drop-down menu of all applicable members). Static typing fanatics try to make us believe that “well-typed programs cannot go wrong”. While this certainly sounds impressive, it is a rather vacuous statement. Static type checking is a compile-time abstraction of the runtime behavior of your program, and hence it is necessarily only partially sound and incomplete. This means that programs can still go wrong because of properties that are not tracked by the type-checker, and that there are programs that while they cannot go wrong cannot be type-checked. The impulse for making static typing less partial and more complete causes type systems to become overly complicated and exotic as witnessed by concepts such as “phantom types” [11] and “wobbly types” [10]. This is like trying to run a marathon with a ball and chain tied to your leg and triumphantly shouting that you nearly made it even though you bailed out after the first mile. Advocates of dynamically typed languages argue that static typing is too rigid, and that the softness of dynamically languages makes them ideally suited for prototyping systems with changing or unknown requirements, or that interact with other systems that change unpredictably (data and application integration). Of course, dynamically typed languages are indispensable for dealing with truly dynamic program behavior such as method interception, dynamic loading, mobile code, runtime reflection, etc. In the mother of all papers on scripting [16], John Ousterhout argues that statically typed systems programming languages make code less reusable, more verbose, not more safe, and less expressive than dynamically typed scripting languages. This argument is parroted literally by many proponents of dynamically typed scripting languages. We argue that this is a fallacy and falls into the same category as arguing that the essence of declarative programming is eliminating assignment. Or as John Hughes says [8], it is a logical impossibility to make a language more powerful by omitting features. Defending the fact that delaying all type-checking to runtime is a good thing, is playing ostrich tactics with the fact that errors should be caught as early in the development process as possible.

It depends on context. There a lot benefits that are appropriate to dynamic typed system as well as for strong typed. I'm of opinion that the flow of dynamic types language is faster. The dynamic languages are not constrained with class attributes and compiler thinking of what is going on in code. You have some kinda freedom. Furthermore, the dynamic language usually is more expressive and result in less code which is good. Despite of this, it's more error prone which is also questionable and depends more on unit test covering. It's easy prototype with dynamic lang but maintenance may become nightmare.

相对于静态类型系统的主要优点是IDE支持和静态代码分析器。 在每次代码更改之后,您都会对代码更加自信。用这样的工具来维护蛋糕是和平的。

摘自Artima的《Typing: Strong vs. Weak, Static vs. Dynamic》文章:

强类型可以防止在不匹配的类型之间混合操作。为了混合类型,必须使用显式转换 弱类型意味着可以在没有显式转换的情况下混合类型

在Pascal Costanza的论文《动态与静态类型——基于模式的分析》(PDF)中,他声称在某些情况下,静态类型比动态类型更容易出错。一些静态类型语言强迫你手动模拟动态类型,以便做“正确的事情”。Lambda the Ultimate讨论过这个问题。

Perhaps the single biggest "benefit" of dynamic typing is the shallower learning curve. There is no type system to learn and no non-trivial syntax for corner cases such as type constraints. That makes dynamic typing accessible to a lot more people and feasible for many people for whom sophisticated static type systems are out of reach. Consequently, dynamic typing has caught on in the contexts of education (e.g. Scheme/Python at MIT) and domain-specific languages for non-programmers (e.g. Mathematica). Dynamic languages have also caught on in niches where they have little or no competition (e.g. Javascript).

最简洁的动态类型语言(例如Perl, APL, J, K, Mathematica)是特定于领域的,并且在它们设计的利基领域中比最简洁的通用静态类型语言(例如OCaml)要简洁得多。

动态类型的主要缺点是:

运行时类型错误。 要达到相同水平的正确性是非常困难的,甚至实际上是不可能的,并且需要大量的测试。 没有经过编译器验证的文档。 糟糕的性能(通常在运行时,但有时在编译时,例如斯大林方案)和由于依赖复杂的优化而不可预测的性能。

就我个人而言,我是伴随着动态语言长大的,但作为一名专业人士,除非没有其他可行的选择,否则不会用40英尺的杆子接触它们。

关于静态语言和动态语言有很多不同的东西。对我来说,主要的区别是在动态语言中,变量没有固定的类型;相反,类型被绑定到值。因此,要执行的确切代码直到运行时才确定。

在早期或naïve实现中,这是一个巨大的性能拖累,但现代jit已经非常接近优化静态编译器的最佳性能。(在一些边缘情况下,甚至比这更好)。