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

也参看: 什么爱的动态语言 (a远远更多的争论的线...)

有帮助吗?

解决方案

解释器推断类型和类型转换的能力使开发时间更快,但它也可能引发运行时故障,而这些故障是您无法在编译时捕获它们的静态类型语言中获得的。但是这些天(以及很长一段时间以来)在社区中热烈讨论哪一个更好(或者即使总是如此)。

对此问题的一个很好的看法来自静态打字需要时可能的动态打字:编程语言之间的冷战结束,Erik Meijer和Peter Drayton在Microsoft:

  

静态打字的倡导者认为   静态打字的优点   包括早期检测   编程错误(例如预防   在布尔值中添加一个整数),   更好的文档形式   类型签名(例如合并   参数的数量和类型   解决名称),更多机会   用于编译器优化(例如   直接替换虚拟呼叫   调用时的确切类型   接收器是静态已知的,   提高运行效率(例如不是   所有价值观都需要携带动态   类型),以及更好的设计时间   开发者体验(例如,了解   接收器的类型,IDE可以   提供所有的下拉菜单   适用的成员)。静态打字   狂热分子试图让我们相信   “良好的节目不能出错”   虽然这听起来肯定   令人印象深刻,它是一个相当空洞的   声明。静态类型检查是一个   编译时的抽象   程序的运行时行为,以及   因此它必然只是部分的   声音和不完整。这意味着   程序仍然可能因为错误而出错   未跟踪的属性   类型检查器,并且有   虽然他们不能去的节目   错了不能进行类型检查。该   使静态打字减少的冲动   部分和更完整的原因类型   系统变得过于复杂   和概念见证的异国情调   例如“幻像类型” [11]和   “摇摆不定的类型” [10]。这就像   试图用球跑马拉松   和链绑在你的腿和   胜利地喊你几乎   即使你拯救了它也成功了   在第一英里之后。

     

动态类型的倡导者   语言认为静态类型是   过于僵硬,而且柔软   动态语言使他们   非常适合原型系统   随着要求的变化或未知,   或者与其他系统交互   这种变化无法预测(数据和数据)   应用程序集成)。当然,   动态类型语言   真正处理必不可少的   动态程序行为,如   方法拦截,动态加载,   移动代码,运行时反射等   在所有论文的母亲   脚本[16],约翰奥斯特豪特辩称   那个静态类型的系统   编程语言使代码更少   可重复使用,更冗长,更安全,   而不是动态的表达   键入的脚本语言。这个   争论被许多人字面上鹦鹉学舌   动态类型的支持者   脚本语言。我们认为   这是一个谬论,落入了   与争论的相同类别   声明性编程的本质是   消除任务。或者约翰   休斯说[8],这是合乎逻辑的   不可能使语言更多   省略功能强大。   捍卫延迟所有的事实   对运行时进行类型检查是一件好事   事情,正在玩鸵鸟战术   应该抓住错误的事实   早在开发过程中就像   可能的。

其他提示

静态型的系统寻求消除的某些错误的静态检查的计划没有运行,并试图证明合理性在某些方面。一些类型的系统能够赶上更加错误的比其他人。例如,C#可以消除的空指针的例外情况时适当地使用,而Java没有这样的功率。Twelf有一种系统,该系统实际上 保证该证据将会终止,"解决"的 停止问题.

然而,没有类型的系统是完美的。为了消除特定类的错误,他们还必须拒绝某些完全有效的计划,这违反了规则。这就是为什么Twelf并没有真正解决终止问题,它只需避免它抛出大量完全有效的证明,它发生到终止在奇怪的方式。同样,Java的类型系统拒绝题的 PersistentVector 实施由于其使用的异构阵列。它的工作在运行,但这类系统不能证实它。

出于这一原因,大多数类型的系统提供"逃脱"的方式复盖的静态检查。对于大多数语言,这些采取的形式铸造的,虽然有些(如C#和Haskell)有整个模式,标记为"不安全"。

主观的,我喜欢静的打字。正确实施(暗示: Java)、静态型系统可以是一个巨大的帮助淘汰的错误之前,他们会崩溃的生产系统。动态类型的语言往往需要更多的单元的测试,这是乏味的最好的时代。此外,静态类型的语言可以具有某些功能,这是不可能或不安全的动态系统类型(隐性转换 春天的头脑)。它是所有问题的要求和主观的味道。我没有更多的建立下一个食在红宝石比我会尝试写一份脚本在大会或增补程序的一个核心使用Java。

哦,谁说的,"x 打字的10倍以上的生产率比 y 输入"只是吹出的烟雾。动态的打字可能的"感觉"快在许多情况下,但它失去实地一旦你实际上试图让你看中的应用程序 运行.同样,静态的打字可能看起来就像是个完美的安全网,但是一看一些更复杂的一般类型的定义在Java发送大部分开发者急于眼眼罩.即使有类型的系统和生产力,也没有银子弹。

最后的注:不要担心业绩时进行比较静态的动态。现代的他喜欢的V8和TraceMonkey来危险地接近静的语言的表现。此外,事实上,Java实际上编制下一个固有动态中间的语言应该是一个提示,对于大多数情况下,动态的打字并不是巨大的性能-杀手,一些人弄出来的人。

嗯,两者都非常,非常非常被误解,还有两个完全不同的东西。 不相互排斥

静态类型是语言语法的限制。严格地说,静态类型语言可以说不是无上下文的。简单的事实是,在上下文无关语法中表达一种语言并不简单地将其所有数据简单地视为位向量变得不方便。静态类型系统是语言语法的一部分,如果有的话,它们只是限制它而不是上下文无关语法,因此语法检查实际上是在源代码的两次传递中发生的。静态类型对应于类型理论的数学概念,数学中的类型理论只是限制了某些表达式的合法性。就像,我不能在数学中说 3 + [4,7] ,这是因为它的类型理论。

静态类型因此不是从理论角度“防止错误”的方式,它们是语法的限制。实际上,假设+,3和区间具有通常的设定理论定义,如果我们删除类型系统 3 + [4,7] 具有非常明确定义的结果,即一组。 “运行时类型错误”理论上不存在,类型系统的实际用途是防止对人类的操作毫无意义。当然,操作仍然只是转移和操纵位。

对此的捕获是类型系统无法决定是否允许运行此类操作。就像在,将所有可能程序的集合完全划分为那些将出现“类型错误”的程序,以及那些不具有“类型错误”的程序。它只能做两件事:

1:证明类型错误将在程序中发生 2:证明它们不会出现在程序中

这似乎与我自相矛盾。但是,C或Java类型检查器所做的是它拒绝一个程序为“不合语法”,或者如果无法在2处成功则称其为“类型错误”。它无法证明它们不会发生,这并不意味着它们不会发生,它只是意味着它无法证明它。一个不会出现类型错误的程序很可能会因为编译器无法证明而被拒绝。一个简单的例子是 if(1)a = 3;否则a =" string"; ,当然,因为它始终为true,所以else分支永远不会在程序中执行,并且不会发生类型错误。但它无法以一般方式证明这些情况,因此被拒绝了。这是许多静态类型语言的主要弱点,在保护自己免受攻击时,在不需要它的情况下,你也必须受到保护。

但是,与普遍认为相反,还有一些静态类型的语言,它们按照原则1工作。它们只是拒绝所有可以证明它会导致类型错误的程序,并且通过所有不能执行的程序。所以它们可能允许在其中包含类型错误的程序,一个很好的例子是Typed Racket,它是动态和静态类型之间的混合。有些人认为你在这个系统中得到了两全其美。

静态类型的另一个优点是类型在编译时是已知的,因此编译器可以使用它。如果我们在Java中做" string" +“string” 3 + 3 ,文本中的 + 标记最后代表一个完全不同的操作和数据,编译器知道选择哪个仅从类型来看。

现在,我将在这里发表一个非常有争议的声明,但请耐心等待:'动态打字'不存在

听起来很有争议,但确实如此,动态类型语言来自理论视角无类型。它们只是静态类型语言,只有one型。或者简单地说,它们是在实践中通过无上下文语法确实语法生成的语言。

为什么他们没有类型?因为每个操作都是在每个操作符上定义和允许的,所以什么是'运行时类型错误'呢?它来自理论上的一个纯粹的副作用。如果执行 print(" string")打印字符串是一个操作,那么 length(3),前者有写的副作用字符串到标准输出,后者只是错误:函数'length'需要数组作为参数。,就是这样。从理论的角度来看,没有动态类型语言这样的东西。它们是无类型

好吧,“动态类型”语言的明显优势是表达能力,类型系统只不过是表达能力的限制。一般而言,如果类型系统被忽略,具有类型系统的语言确实会为所有那些不允许的操作定义结果,结果对人类没有意义。应用类型系统后,许多语言都失去了图灵的完整性。

明显的缺点是可能发生的操作会产生对人类无意义的结果。为了防范这种情况,动态类型语言通常会重新定义这些操作,而不是产生无意义的结果,而是将它重新定义为具有写出错误的副作用,并可能完全停止程序。这根本不是一个“错误”,事实上,语言规范通常意味着这一点,这与从理论角度打印字符串一样多的语言行为。类型系统因此迫使程序员推断代码流,以确保不会发生这种情况。或者实际上,发生发生的原因在某些方面也可以派上用手进行调试,这表明它根本不是一个“错误”,而是一个定义良好的语言属性。实际上,大多数语言所拥有的“动态类型”的单一残余是防止除零。这就是动态类型,没有类型,没有更多的类型,零是与所有其他数字不同的类型。人们称之为“类型”的只是数据的另一个属性,比如数组的长度或字符串的第一个字符。许多动态类型语言也允许你写出诸如之类的错误:这个字符串的第一个字符应该是'z'"

另一件事是动态类型语言在运行时具有可用的类型,通常可以检查它并处理它并从中做出决定。当然,理论上它与访问数组的第一个字符并查看它是什么没有什么不同。实际上,你可以创建自己的动态C,只使用一个类型,如long long int,并使用它的前8位来存储你的'type'并相应地写函数来检查它并执行浮点或整数加法。您有一种静态类型语言,只有一种类型或动态语言。

在实践中,所有节目中,静态类型语言通常用于编写商业软件的上下文中,而动态类型语言倾向于在解决某些问题和自动化某些任务的上下文中使用。用静态类型语言编写代码只需要很长时间并且很麻烦,因为你不能做你知道的事情会好转,但类型系统仍会保护你免受你自己的错误。许多程序员甚至没有意识到他们这样做是因为它在他们的系统中,但是当你用静态语言编写代码时,你经常会解决类型系统不会让你做出不会出错的事情的事实,因为它无法证明它不会出错。

就像我一样

也许最大的一个"受益"的动态型的浅的学习曲线。没有类型的系统学习并且没有不小的语法角情况下,这种类型的限制。这使得打字动态可以有更多的人和可行的为许多人对他们来说,复杂的静态系统类型是达到。因此,动态的打字已经引起了在环境教育(例如方案/蟒蛇在麻省理工学院)和领域特定语言为非程序员(例如 Mathematica).动态语言还在壁龛,他们很少或没有竞争(例如Javascript)。

最简洁的动态型的语言(例如Perl,APL,J,K, Mathematica)是特定领域,可以明显更加简明扼要的最简洁的通用静态型的语言(例如 OCaml)在壁龛他们被设计为。

主要缺点的打字动态是:

  • 运行时间类型的错误。

  • 可能是非常困难甚至几乎不可能达到相同水平的正确性,并需要远远更多的试验。

  • 没有编译器验证的文件。

  • 可怜的绩效(通常是在运行时间,但有时在编制时间,而不是的,例如斯大林方案)和不可预测性能由于依赖复杂的优化。

就个人而言,我长大了,在动态的语言但是不会接触它们有40'极为专业的,除非没有其他可行的选择。

来自Artima的 打字:强与弱,静态vs.动态 文章:

  

强类型可防止不匹配类型之间的混合操作。要混合类型,您必须使用显式转换

     

弱类型意味着您可以在没有显式转换的情况下混合类型

在Pascal Costanza的论文中, 动态与静态打字—基于模式的分析 (PDF),他声称在某些情况下,静态类型比动态类型更容易出错。某些静态类型语言会强制您手动模拟动态类型,以便执行“正确的事情”。它在 Lambda the Ultimate 中进行了讨论。

这取决于背景。有很多好处适用于动态类型系统以及强类型系统。我认为动态类型语言的流程更快。动态语言不受类属性和编译器思考代码中发生的事情的约束。你有一些自由。此外,动态语言通常更具表现力,并且导致更少的代码,这是好的。尽管如此,它更容易出错,这也是有问题的,更多地取决于单元测试覆盖。这是一个简单的原型与动态郎,但维护可能会变成噩梦。

静态类型系统的主要优势是IDE支持,并且肯定是代码的静态分析器。 每次代码更改后,您都会对代码更有信心。维护是这种工具的和平蛋糕。

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

在早期或未实现的实现中,这是一个巨大的性能拖累,但现代JIT与优化静态编译器所能获得的最佳结果非常接近。 (在某些边缘情况下,甚至比这更好)。

这是关于工作的正确工具。 100%的时间都不会更好。这两个系统都是由人创造的并且有缺陷。对不起,但我们很糟糕,做得很好。

我喜欢动态类型,因为它不受我的影响,但是运行时错误可能会升级,我没有计划。 静态类型可能会修复上述错误,但驱动新手(在类型语言中)程序员疯狂尝试在常量字符串和字符串之间进行转换。

静态打字: Java和Scala等语言是静态类型的。

必须先定义和初始化变量,然后才能在代码中使用它们。

代表。 int x; x = 10;

的System.out.println(X);

动态打字: Perl是一种动态类型语言。

在代码中使用变量之前,无需初始化变量。

Y = 10;在代码的后半部分使用此变量

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top