可以将静态和动态类型的语言视为用于不同类型工作的不同工具吗?


9

是的,曾经提出过类似的问题,但总的目的是找出“哪个更好”。

我之所以这样问是因为我最初是作为一名开发人员来使用JavaScript的,并且实际上并没有在使用静态类型语言编写方面的丰富经验。

尽管如此,我肯定会发现学习C语言在较低级别的代码上处理苛刻的操作的价值(我认为这在编译器级别与静态与动态有很大关系),但是我想尽力而为是否存在特定的项目上下文(也许是某些类型的动态数据密集型操作?)涉及性能以外的其他方面,因此与Java或C#相比,与Python之类的东西更有意义。


5
答案是“是”。每种语言-实际上是每种语言-都有其优点和缺点,因此比其他语言更适合某些任务。
克里斯·

有趣的是,您使用C作为示例,因为它是一种最弱类型的语言,您可以想像却仍称其为静态类型。由于类型系统,C的运行速度并不快,类型检查发生在编译时。C速度快是因为几乎没有安全措施和检查措施,无法防止您用脚射击。并且因为它可以编译为本地二进制文件。
萨拉

Answers:


10

当然是。
在您希望能够将所有内容都视为一种类型的情况下,动态类型化具有绝对的优势。序列化/反序列化是经典示例之一。这就是为什么这么多的Web编程是用动态类型的脚本语言完成的原因:它们非常适合一项涉及大量数据在字符串之间来回转换的任务。

另一方面,对于应用程序编程,静态语言的效果要好得多,因为尝试将所有内容都视为一种单一类型并不是经常需要的。您通常希望拥有高效的数据结构,并且将数据表示为自身,而不是非常频繁地转换为其他类型。这使动态类型化功能成为缺点而不是优点,这就是为什么应用程序几乎完全用静态类型化语言编写的原因。


3
@Erik:我不确定我是否会这么说。在开发过程中,事情会发生变化。需求可能会更改,或者您发现自己未正确实施需求,因此需要更新代码。能够更改一件事并使用生成的编译器错误向您展示在哪里可以找到需要更改的所有其他内容,这极大地提高了您在使用该技术无法使用的语言时所失去的便利性和开发速度。这就是为什么您看不到以动态语言开发的复杂应用程序的原因之一。
梅森·惠勒

9
@Mason Wheeler:很好的答案。+ 1我要补充一点,静态类型检查还可以通过让编译器检查类型正确性来帮助更早地发现错误。例如,昨天我调试了一个200行的Ruby程序,有两个与类型有关的错误,只有通过运行该程序才能检测到。我不想考虑在100000行项目中会发生什么。因此,动态类型为您提供了更大的灵活性,这在您所描述的上下文中是很好的,但代价是在编译时找不到某些错误。因此,静态类型不仅与效率有关,而且与正确性有关。
乔治

1
@MasonWheeler两年后,C#和Java比我所讨价还价要多得多,现在我将不同意一些事情。复杂的Web应用程序完全使用动态语言完成。当您可以进行立即可见的更改时,编译与运行时间毫无意义。而且我已经提出一种观点,即在程序语言中,所有对类型的麻烦都比在应该由OOP驱动的语言中更有意义,因为在OOP中,数据一开始就不应该经常变迁。
Erik Reppen

1
@Erik:* wince *首先,用Java将静态类型判断为概念就像将Pinto判断为汽车一样。其次,根据定义,任何可以“立即看到”更改的东西都不是非常复杂的程序,因为即使使用现代硬件,复杂的程序也需要花费大量时间来准备代码,无论是编译器还是解释器(或JIT编译器)进行准备。即使是最令人印象深刻的Web应用程序也往往是由非常复杂的数据库支持的非常简单的程序,这是完全不同的事情。
梅森惠勒2013年

1
进行复杂抽象的能力与具有静态与动态类型的系统正交,并且与速度正交。那里有静态类型系统,它们允许强大的(尽管有时是奥秘的)抽象。具有立即出现的更改也与类型系统无关:您当然可以为静态类型的语言构建解释器。
Rufflewind

4

我的看法是,如果您可以在静态类型的语言中自然地工作,那么静态类型就是可行的方法。通常,类型系统的目的是防止您使用未定义的语义(例如)执行操作(string) "hello" + (bool) true。即使没有进行大量的单元测试,具有防止您执行这些操作的额外安全级别也是防止代码中错误的好方法。也就是说,类型安全性对代码的语义正确性提供了另一种置信度。

但是类型系统很难正确处理。我不相信有在写这篇文章的时候了完善的类型系统的性质。(“完美类型系统”是指严格的类型系统,它不需要冗长的代码注释,不会产生假阳性的类型错误,并且程序员易于理解其类型错误。)此外,它还可以很难理解确实存在的真正好的类型系统。当我学习Haskell时,我无法告诉您尝试写对我来说看起来像正确代码的代码时出现的模糊类型错误的数量。通常,代码实际上是不正确的(这是对类型系统的支持),但是花了很多时间工作,以了解来自编译器的错误消息,以便我可以更正潜在的问题。在OO语言中,您可能最终会发现自己在想“此参数应与输入类型相反而不是协变!”,或者(更有可能)恢复为类型转换以逃避类型系统的范围。类型系统比您想象的要棘手得多。

对于它的价值,我的理解是,提出好的类型系统的困难是促使Gilad Bracha在Newspeak中加入可插拔类型系统支持的部分原因。


我完全同意WRT单元测试。您总是看到人们说“如果您有良好的单元测试,他们可以为您验证类型的正确性”。这总是让我想起Paul Graham(他坚信动态键入始终是一件好事)是如何说的,一种使您手动执行编译器工作的语言是一种有缺陷的语言。Sorta让您停下来思考……
Mason Wheeler

我认为,许多关于动态类型语言“危险”的问题都没有考虑到我们如何编写这些内容。许多Python和JS都可以用控制台风格编写。螺丝编译与运行时比较,我现在可以尝试一下,看看会发生什么。不过,我认为您的观点很不错。当所有所谓的优秀浏览器供应商提供令人困惑的可怕代码传递而IE6或7出乎意料之外时,没有什么比让我对客户端Web开发更疯狂的了。以更典型的方式吮吸。
埃里克·雷彭

@ mason-wheeler不匹配类型是简单的错误,不是动态语言不检查类型,而是在运行时。我的经验是,大多数静态语言都具有相同级别的单元测试覆盖范围,它们不会因编译器提前检查类型而丢失任何测试,而动态语言则不必添加特定测试来检查类型,运行时系统会检查您的类型,如果您的单元测试覆盖了您的方法,它将捕获它们。
jbtule

4

它们是不同的工具,但不是根据性能。这都是关于复杂性的

动态语言通常以最大的灵活性为目标,并且带来了缺乏验证和某种保证的情况。然后,它在小型程序中非常强大,但是维护大型程序(复杂性)几乎变得不可能。

静态语言通常旨在最大程度地验证。他们的首要目标通常是尽早发现错误(或错误)。为验证提供了很多保证。这样一来,学习和启动起来就更加困难,但是随着程序的扩大,它可以以更少的成本(编码工作量)提供更好的程序验证。

结果,动态语言通常适合小型(我的意思是很小)程序,例如动态网页,Web浏览器DSL(不适用于浏览器应用程序!)或Shell脚本。静态语言更适合于系统编程或其他任何东西。

上面的描述是关于非常纯动态或静态语言的。大多数现实生活中的语言都在它们之间,并且表现出各种特征。

请参阅此处以获取更多详细信息:https : //softwareengineering.stackexchange.com/a/105417/17428


1
“动态语言通常适合于小型(我的意思是很小的)程序”:以我的经验,您也可以将动态语言用于中型应用程序(当然,有人在大型应用程序中成功使用了动态语言)。我同意代码库越大,您就可以从静态语言提供的静态检查中获益更多。
乔治

2
@Giorgio好吧,这也许是因为我沉迷于静态验证方面。这对我
真是太好

我看到了静态语言的优点(并且我赞成您的回答)。最近,我一直在使用Python和Common Lisp,并且我承认在实践中,如果使用简洁的设计,尤其是在Python中,如果编写了足够的测试,您会获得良好的结果。这些语言对于构建原型很有效,然后可以轻松地将其转化为您的生产代码。但是,是的,对于更复杂的项目,我希望获得尽可能多的帮助,所以我更喜欢静态语言。
乔治

1

我目前使用静态类型语言(C#和F#)进行编程,但是我喜欢使用动态语言(Smalltalk,Ruby)进行编程。人们将一种类型与另一种类型相关联的利弊很多,而与强制实施类型相比,更多的是关于语言的。例如,动态语言通常具有更简洁明了的语法,但是F#和OCaml及其类型推断系统的语法与任何动态语言一样干净。有了静态类型,您便具有真正的自动重构和自动完成功能,但是Smalltalk以及数据库中的全部源代码和单独编译的每种方法,是真正具有认真的自动重构功能的第一门语言,而且效果很好。最终,当今的现代动态和静态语言都是类型安全的,这是类型系统中最重要的方面,


我有时怀疑静态类型只是使语言或多或少具有灵活性的方程式的一小部分。我认为我也开始意识到,许多开发人员更喜欢使用一组舒适的导轨来引导它们,而不是自由支配做诸如过载操作员之类的荒唐危险的事情。VS让我有时想踢小狗,但是我对F#一直很好奇,而你所说的让我更加好奇。我认为这不仅是C#,还可以隐式转换为更具包容性的类型。
埃里克·雷彭

@erik,哦,不仅仅是隐式输入和var:F#类型推断
jbtule 2011年

-1

现在是2015年,在对话中添加了一些有趣的摘要:

  1. 企业后端世界的重要部分正在考虑或开始使用Python(动态)代替Java(严格为静态)
  2. 企业前端世界正在看到基于TypeScipt的AngularJS v2之类的东西:TypeScipt 是Javascript 的类型化扩展。

因此,后端人员厌倦了不必要的严格打字,而前端人员厌倦了动态打字的混乱。

颇具讽刺意味的是:我想知道他们是否会在中间相遇,或者随着截止日期过去的声音热潮相互冲撞……?;)


除非您提供任何证据,否则我会声称,在最坏的情况下,后端世界正在过渡到Go,但是上帝禁止任何动态的脚本内容。静态编程语言总是要举行很多仪式的神话早已被更强大的推理系统和可靠的REPL实现所揭穿
2015年

大量使用动态类型化的后端。尤其是Django,在新闻界非常受欢迎,并且在NYT,《卫报》和《华盛顿邮报》的后台运作。沃尔玛在Node上运行。唯一的误解是没有静态类型就无法为规模写代码。在花了一些时间思考我遇到的一些Java遗留代码库灾难之后,我认为对此感到满意的人,无论是使用静态还是动态的,都对它更好。
埃里克·雷彭

确实,我宁愿在大型企业项目中拥有一支熟练的Python团队,而不是一个差劲的Java团队。只需澄清一下我的立场:我发布了以上答案作为对
Cornel Masson

确实,我宁愿在我的大型企业项目中拥有一支熟练的Python团队,而不是一个贫穷的Java团队。只是为了澄清一下:我发布了以上答案,作为对我在客户群,行业网络和一般研究中看到的趋势的观察。传统上严格的后端拥抱较少的严格性,传统上宽松的前端则更多。甚至没有关于哪个“正确”(如果有)的观点-不知道为什么我被否决了。也许讽刺意味消失了……
Cornel Masson
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.