13

当您选择静态类型语言如 Scala(或 F#、Haskell、C#)而不是动态类型语言如 Ruby、Python、Clojure、Groovy(具有宏或运行时元编程功能)时,您在实践中会失去什么?请考虑最好的静态类型语言和最好的(在您看来)动态类型的语言,而不是最差的语言。

答案摘要

像 Ruby 这样的动态语言相对于像 Scala 恕我直言的静态类型语言的主要优势是:

  • 快速编辑运行周期(JavaRebel 是否缩小了差距?)
  • 目前 Scala/Lift 的社区比 Ruby/Rails 或 Python/Django 小得多
  • 可以修改类型定义(尽管动机或需要不是很清楚)
4

7 回答 7

9

原则上,当不清楚(在静态上下文中)正确的做法是什么时,您放弃了忽略您正在使用的类型的能力,仅此而已。

由于复杂的类型检查可能相当耗时,您也可能被迫放弃快速在线元编程。

在实践中,使用 Scala,您几乎不会放弃其他任何东西——也没有我特别关心的东西。您不能注入新方法,但可以编译和运行新代码。您必须在函数参数中指定类型(以及递归函数的返回类型),如果您自己从不犯类型错误,这会有点烦人。由于它编译每个命令,Scala REPL 不像 Python shell 那样灵活。并且由于它使用Java 反射机制,因此您不会像使用Python 那样轻松地进行在线检查(无论如何,如果没有构建自己的检查库)。

于 2010-04-02T14:27:40.803 回答
4

选择哪种静态或动态语言比静态/动态选择本身更重要。一些动态语言具有良好的性能和良好的工具。一些静态语言可以简洁、富有表现力和增量。有些语言几乎没有这些品质,但确实拥有大量经过验证的代码库。

于 2010-04-02T12:53:47.333 回答
3
  1. 动态语言往往具有更灵活的类型系统。例如,Python 允许您将新方法注入现有类,甚至注入单个对象。
  2. 许多(不是全部)静态语言缺乏构造复杂文字的工具。例如,像 C# 和 Java 这样的语言不能轻易模仿下面的 JavaScript { 'request':{'type':'GET', 'path':mypath}, 'oncomplete':function(response) { alert(response.result) } }
  3. 动态语言具有非常流畅的语义。Python 允许导入语句、函数定义和类定义出现在函数和if语句中。
  4. eval是大多数动态语言和少数静态语言的主要内容。
  5. 由于必须完全指定函数参数类型的尴尬,动态语言中的高阶编程(在我的主观意见中)比静态语言更容易。
    • 这对于递归 HOP 结构尤其如此,其中类型系统确实会妨碍。
  6. 动态语言用户不必处理协变和逆变。
  7. 通用编程在动态语言中几乎是免费的。
于 2010-04-02T12:32:13.037 回答
3

我不确定除了简单之外你是否会失去任何东西。静态类型系统一个额外的学习负担。

我想你通常也会输eval,但我从不使用它,即使在动态语言中也是如此。

我发现在选择用于给定任务的语言时,问题更多地在于其他所有方面。在解决语言问题时,工具、文化、库都比打字更有趣。

另一方面,编程语言研究则完全不同。:)

于 2010-04-02T15:15:30.077 回答
1

我的2美分...

IMO(强)静态类型语言可能会减少必要的测试代码量,因为其中一些工作将由编译器完成。另一方面,如果编译步骤相对较长,则更难进行“增量式”编程,这在现实生活中可能会导致只测试通过编译器的容易出错的代码。

另一方面,动态类型语言感觉改变事物的门槛较低,这可能会减少从错误修复和改进的角度来看的响应时间,因此可能会在应用程序开发过程中提供更平滑的曲线:处理常量与处理出现在错误块中的更改相比,小更改的流程更容易/风险更小。

例如,对于设计非常不清楚并且应该经常更改的项目,使用动态语言可能比使用静态语言更容易,如果它有助于减少不同部分之间的相互依赖关系。(虽然我不坚持那个:))

我认为 Scala 介于两者之间(例如,您不必显式指定变量的类型,与例如 C++ 相比,这可能会简化代码维护,但如果您最终对类型做出错误的假设,编译器会提醒关于它,不像在 PHP 中你可以写任何东西,如果你没有很好的测试来覆盖这个功能,你注定要在一切都在流血的时候发现它)。当然可能是非常错误的:)

于 2010-04-07T17:59:22.567 回答
1

Steve Yegge herehere以及主要攻击 Scala 类型系统复杂性的Guido van Rossum都表达了对 Scala 的一些批评。他们显然不是“Scala 程序员”。另一方面,这里有一些来自 James Strachan 的赞美

于 2010-04-02T20:51:48.140 回答
0

在我看来,静态类型和动态类型之间的区别归结为编码风格。尽管 Scala 中存在结构类型,但大多数时候程序员都在考虑对象的类型,包括 trait 等很酷的小工具。另一方面,我认为 Python/Javascript/Ruby 程序员根据对象的原型(方法和属性的列表)来思考,这与类型略有不同。

例如,假设有一个名为的类家族,Vehicle其子类包括PlaneTrainAutomobile; 以及另一个类家族,Animal其子类包括CatDogHorse。Scala 程序员可能会创建一个称为 traitTransportation或具有

def ride: SomeResult
def ride(rider: Someone): SomeResult

作为会员,她既可以处理,也可以Train作为Horse交通工具。Python 程序员只需传递 train 对象而无需额外的代码。在运行时,语言会发现对象支持ride.

方法调用在运行时解析的事实允许 Python 和 Ruby 等语言拥有重新定义属性或方法含义的库。一个很好的例子是 O/R 映射或 XML 数据绑定,其中未定义的属性名称被解释为表/XML 类型中的字段名称。我认为这就是人们所说的“灵活性”。

在我使用动态语言的非常有限的经验中,我认为只要你不犯错误,用它们进行编码会更快。并且可能随着您或您的同事擅长使用动态语言进行编码,他们会犯更少的错误或开始编写更多的单元测试(祝你好运)。在我有限的经验中,我花了很长时间才发现 Scala 可以在一秒钟内捕获的动态语言中的简单错误。在编译时拥有所有类型也使重构更容易。

于 2010-04-04T17:32:37.583 回答