什么使编程语言具有动态性?

Gai*_*ter 40 static programming-languages dynamic

什么使编程语言被称为动态语言?我应该使用动态编程语言来解决哪些问题?静态编程语言和动态编程语言之间的主要区别是什么?

Kur*_*out 30

我不认为这里有黑色和白色 - 动态和静态之间存在着完整的光谱.

让我们为频谱的每一侧采用两个极端的例子,看看它带给我们的地方.

Haskell是静态方向的极端.

  • 它有一个强大的类型系统,在编译时检查:如果你的程序编译它没有常见的错误,也没有那么常见的错误.
  • 编译后的表单与haskell程序(它是二进制文件)非常不同.因此,运行时反射和修改很难,除非你已经预见到了.与解释原始数据相比,结果可能更有效,因为编译器可以自由地进行时髦的优化.

因此,对于静态语言,我通常认为:需要相当冗长的编译时分析,类型系统将阻止我犯下愚蠢的错误,但也会阻止我做一些实际上有效的事情,如果我想在运行时对程序进行任何操作,它会有点痛苦,因为程序的运行时表示(即它的编译形式)与实际语言本身不同.如果我没有预见到,稍后修改一些东西可能会很痛苦.

Clojure是动态方向的极端.

  • 它也有一个类型系统,但在编译时没有类型检查.许多常见错误只能通过运行程序来发现.
  • Clojure程序本质上只是Clojure列表(数据结构),可以这样操作.因此,在进行运行时反射时,您实际上或多或少地处理Clojure程序,就像您键入它一样 - 运行时表单非常接近编程语言本身.因此,您可以在运行时基本上执行与"键入时间"相同的操作.因此,运行时性能可能会受到影响,因为编译器无法进行许多前期优化.

对于动态语言,我通常认为:简短的编译步骤(基本上只是阅读语法),快速和渐进式开发,几乎没有限制它允许我做什么,但不会阻止我犯愚蠢的错误.

正如其他帖子所指出的那样,其他语言试图采取更多的中间立场 - 例如F#和C#等静态语言通过单独的API提供反射功能,当然也可以通过使用F#的REPL等聪明的工具来提供增量开发.动态语言有时提供可选的类型(如Racket,Strongtalk),并且通常看起来有更先进的测试框架来抵消编译时缺乏任何健全性检查.同时键入提示,虽然未在编译时检查,但是有用的提示可以生成更高效的代码(例如Clojure).

如果您正在寻找针对特定问题的正确工具,那么这肯定是您可以看到的维度之一 - 但本身不可能以任何方式强制做出决定.考虑一下您正在考虑的语言的其他属性 - 它是功能性的还是OO或逻辑或......语言?它对我需要的东西有一个很好的框架吗?我是否需要稳定性和二进制向后兼容性,或者我可以在编译器中使用一些流失?我需要大量的工具吗?等等.

  • 为了回应你的前两条评论,我更新了一些内容.在你的第三个评论:是的,我指的是引用.根据我的经验,Lisp-y引用比F#中的引用更容易理解和处理,正是因为语言越静态,引用与您输入的内容之间的差距就越大.在Clojure中,你"基本上输入AST并将其恢复原样 - 在F#中,例如匹配语句转换为引号中的匹配树(if-then-else).另外,没有评估等. (2认同)

Jar*_*dek 8

动态语言在运行时执行许多任务,静态语言在编译时会执行这些任务.
有问题的任务通常是以下一个或多个:类型系统,方法调度和代码生成.

这也几乎回答了有关其使用的问题.


Mar*_*ers 6

使用中有许多不同的定义,但一个可能的区别是:

  • 一个动态语言通常使用动态类型.
  • 一个静态语言通常使用静态类型.

某些语言很难分类为静态或动态类型.例如,C#传统上被认为是静态类型语言,但C#4.0引入了一种静态类型dynamic,在某种程度上表现得更像动态类型而不是静态类型.

  • @Jon Harrop:是的,我经常听到这个.很多人使用的另一个定义是static = compiled,dynamic = interpre.Python通常被视为动态语言,包括编译为字节代码的编译器 - 类似于Java类文件.`pyc`文件是编译后的文件.因此,我认为这个定义是不合适的,因为它意味着Python是一种静态语言.由于这些条款没有官方定义,我猜你不能真正说出谁是对错. (3认同)