大家好
不久前,我们印制了Odersky,Spoon和Wenners编写的有关Scala 2.12的书。 毕竟,到Scala 3还是很遥远。
今天的文章作者是SoftwareMill的共同创始人,经验丰富的Scala开发人员Adam Worski。 他对现代Scala语言的优势进行了有趣的总结,请您注意。
在Martin Odersky在ScalaDays上进行了一次
全体演讲后,他概述了Scala 3的计划,并在Scalapeño会议上就John de Goes进行了关于
Scala未来的
全体演讲,之后
在Scala社区中继续进行
了热烈的讨论。 除了这些全会演讲的讨论之外,在Twitter,Slack社区以及reddit中都进行了许多讨论(例如,参见
1、2 )。
这就是问题!对于已经在Scala生态系统中工作的专家来说,所有这些都是非常有趣和有益的。 但是,许多争议与Scala作为一种语言在各种直观上可感知的或实际的缺陷有关。 这些时刻可能使人们“从外面”吓到他们,问他们以下问题:“我为什么要完全使用Scala?”,“如果这是死路一条呢?”,“ Scala 3会重复Python 3的成功吗?” 等 在大多数讨论中,最薄弱和最动人的话题正在引起人们的注意,这场辩论也不例外。
因此,让我们
退后一步 :为什么您甚至需要Scala? 使用该语言的技术和业务原因是什么?
项目主题区首先,Scala语言特别适合某些学科领域(但并非对每个人都适用!)。 Scala最重要的资产是它
在定义抽象方面的灵活性 。 您可以随意使用-一些简单的“砖块”; 有时定义抽象并不比使用类,方法和lambda表达式困难。 有时您必须使用隐式参数或扩展方法。 在极少数情况下,仍然只能诉诸宏命令。 但是,
有一些选择 。
因此,如果您需要
浏览复杂的主题区域 ,Scala非常适合您。 例如,我们可以谈论分布式或竞争性编程。 并发非常困难,Scala有许多库通过构建抽象来简化此任务。 有两种主要方法:使用
Akka实现的actor,以及本着FP精神,由
Monix /
cats-effect和
Scalaz /
ZIO提出 (如果您想了解有关比较这些工具的更多信息,我就该主题撰写了
一系列文章 )
但是,当然,我们可以谈论其他主题领域。 Scala的功能还使我们能够将典型业务应用程序的建模提升到一个新的水平。 但是在这种情况下,我们谈论的是不同顺序的复杂性。 对于分布式系统,我们面临着技术复杂性。 在应用程序中对业务逻辑进行编程时,我们已经在谈论主题领域的复杂性。 例如,Debasish Ghosh的书《
功能和反应域建模 》介绍了如何将DDD与功能和反应编程结合在一起。
语言难度注意:在谈论Scala时,每个人都喜欢强调这种语言的广泛性,强调正是由于这种多功能性,该语言是如此复杂。 这并非完全正确。
如上所述,Scala具有许多可用于构建抽象的基本构造。 但是,所有语言都可以相互
组合 ,因此该语言具有这种灵活性。 您可能遇到的大多数创新项目都归结为高阶类型,隐式参数和子类型的一种或另一种组合。
因此,由于具有相对较少的基本功能(Scala语法的大小比Kotlin,Java或Swift!更简单),从而方便了学习,因此组合选项就很多了。
选择范围是否太大? 我不这么认为。 作为主管和负责任的专业人员,程序员不仅能够选择最佳选项来解决特定的问题。 有关更多信息,请参见文章“
Simple Scala Stack ”。
Java更好现在有很多人谈论
Kotlin将 Scala取代为“像Java,只有更好”。 但我认为仍然应该
冠以Scala而非Kotlin的称号。 这样做的主要原因有两个:
首先,
Scala的不变性至关重要 。 这是由于Scala的特性所致:主要在不可变数据的帮助下,在它上面编写代码很方便。 此类数据尤其包括:
val
(作为第一类的单位),
case
类,高阶函数等。 但是关键是如何设计和编写标准的Scala语言库。 默认情况下使用的所有数据结构都是不可变的。 由于具有不变性,因此简化了许多事情,尤其是在我们竞争激烈的世界中,这些语言获胜,因此首选不变性。
其次,Scala支持
类型构造函数,高阶类型和类类型 (隐式声明),这大大简化了包装/容器类型的工作,例如
Promise
,
Future
或
Task
。 当使用异步或响应式编程时,此类包装器将占上风。例如,简化了积极使用
Future
的代码库的工作的语言结构的存在是支持Scala的另一个理由。
什么是课程类型? 它们的作用与Java中的设计模式大致相同,但是,只要您牢牢把握其含义,它们就会变得更加灵活且易于使用。 有一些很好的指南,例如
1,2 。
那类型构造函数呢? 这些是诸如
Future
或
Option
类的类型,用作其他类型的“容器”或“包装器”。 因此,您可以使用
Option[String]
或
Future[Int]
。 高阶类型允许您编写抽象任何包装器的代码。 参见例如。
1,2 。
您突然想知道,为什么还要诉诸于
Future
/
Task
? 关键不仅在于使用异步I / O来执行具有最小延迟的大多数高性能“反应式”计算,为此仅需要此类设计。 在
有关reddit的讨论中以及我的文章“
为什么要对包装程序打扰? ”中给出了其他原因
。 ”
在主要未更改的环境中工作,以及能够方便地处理诸如
Future
,
Promise
或
Task
(并抽象化它们!)的能力,彻底改变了您的代码。 乍一看,这可能并不明显:如果您具有Java或Ruby的经验,那么您将无法立即实现Scala的这些方面。 但是,即使从教育的角度来看,了解“功能性”方法的工作方式也是很有用的,更重要的是,为什么它可以证明是
非常值得的选择 。
自然地,Scala和Kotlin都比Java具有许多共同的优势,例如:
- 更紧凑的语法
- 较少刻板的代码
- 丰富的类型系统
- 缺乏语言镇流器
同时,两种语言都提供对库和JVM框架生态系统的访问。
类型系统越丰富(在Scala中,它比Kotlin中要丰富,而Kotlin中则比Java中要丰富),那么由编译器而不是由人执行的验证工作就更多。 为此,创建了计算机:执行无聊的例行重复性任务。 检查类型的适用性绝对只是这些任务之一。
同时,丰富类型系统不仅在
编写代码时有用,而且在
阅读代码时更大程度上也很有用。 当您轻松浏览代码库,了解代码的作用,并且进行
重构时并不害怕(或不太害怕)时,从技术和应用的角度来看,这都非常积极地表征了该语言。
FP与OOP在此类讨论中经常提出的另一个问题是,Scala语言是应该继续坚持OOP和FP的综合,还是应该沿着纯粹的功能发展。 我是综合的
支持者 ,特别是因为我认为FP和OOP不是替代方法,而是相辅相成的。
FP
使用函数 (尽管不是全部)进行
编程 ,但它们是参照透明的(请参见在较早的线程中
对reddit的回答 ,其中对参照透明进行了很好的说明)。 在OOP中,使用“消息”或在我们的术语中对虚拟方法的调用来组织与对象的通信。 这两种方法不能共存是没有单一原因的,Scala已经证明了这一点!
在
有关Scala优点的推文中, John de Goes提到了一些在纯功能方法中有用的OOP功能,特别是
一流模块 (通过组合对象获得),
点语法 (对象中的调用方法)以及作为一流构造的
类 /类型
实例。 。 所有这些都是两个范式成功结合的要素。 也许更多指日可待?
“综合”项目尚未完成;这里肯定有一个讨论的领域。 一个不完整的方面是所提出的扩展方法语法,该语法应替代更多混乱的隐式转换。 另一个是优化类型类的语法。 前一阵子
提出的建议显然是粗略的,并未涵盖Scala中最常见的monad使用。 有些建议比较好,有些则需要改进,但是最好是收到建议并就这些建议进行讨论。 多亏了他们,语言才得以生存,并且最终,最佳的解决方案得以固定。
斯卡拉3Scala 3将在两年内发布。 其中将出现许多有趣的可能性,特别是不透明类型,特征参数,新的元编程方法,并集和&交集类型,隐式函数类型-这些仅是几个示例。 当然,对迁移存在(有充分根据的)担忧。
众所周知,将使用一种特殊的工具使用
scalafix将
代码从Scala 2
自动迁移到Scala 3。 由于Scala是一种静态类型的语言,因此可以大规模解决此类任务,并且比Python中的任务简单得多。 但是,当然,这里没有魔术:即使此工具提供了99%的正确代码覆盖率,仍将保留1%的最有问题的案例。 由于您无法依靠魔术,因此这些片段的迁移将需要手动完成。
这些是使用积极发展的语言进行工作的成本:您可以获得最新的机会,但实际上其中一些机会并不是很好,需要加以改进。 即使这样,建议的更改也不是革命性的。 Scala 3语言与Scala 2非常相似,预计不会发生重大的范例变化。
令人鼓舞的是,Scala团队认真对待迁移。 较早版本的Scala之间的迁移(例如从2.8到2.9)非常繁重,而最近的迁移则要好得多。 涉及三个主要方面:EPFL,
ScalaCenter和
Lightbend (通常一起)共同努力促进迁移。 例如,有一个二进制兼容的
MIMA工具,并且社区中不断创建许多新的库,以确保使用新版本的Scala可以方便地工作。
最后,尚未完成的TASTY工具(因此尚无法评估)应确保使用从Scala 2到Scala 3的二进制文件。
那么,为什么要使用Scala?那么,如果从业务角度考虑这种语言,那么停在Scala的原因是什么呢? 以上所有技术优势对企业直接有用。 当您使用一种语言可以编写带有更少错误的复杂代码时,就会为您提供最少的术语延迟和满意的用户。 如果您开始为Scala编写功能强大,几乎防滑的竞争性应用程序,而Scala中提供了专用工具,那么这将为您的公司带来巨大的好处。
此外,不要忘了
Spark (
分布式数据分析的领先平台)。 Scala不仅用于实现Spark这样,还用于定义计算本身。 这是另一个面向数据科学的抽象,它隐藏了复杂的计算模型。
总结当然,Scala中存在问题,但问题不在哪里? 乐观的原因是,许多每天使用Scala的人都在积极地
改善工具 ,库和语言本身。 我可以假设他们继续与Scala一起工作的原因恰恰是因为,尽管存在所有缺点,但没有一种语言非常适合他们的学科领域。
Scala允许您开发自己的编程风格,而不论以前使用的是哪种语言:Java,Ruby或只是尝试编程。 Scala没有唯一的制胜法宝。 要么是Akka更加
当务之急的方法,要么是Cats and Scalaz更加
实用的方法。
在这里可以看到问题所在:Scala社区中的某些部分坚持“反应性”,“合成” OOP / AF方法和纯AF。 但是,实际上,这是一个巨大的优势。 由于这种多样性,进行了讨论,从不同的角度表达了许多不同的意见。 这样一来,您就可以完美地学习如何解决非标准问题并丰富自己的工具。
无论您在Scala中选择哪种方式,都会有一群参与库和框架开发的令人印象深刻的同事支持您; 这些人随时准备帮助和讨论新出现的想法。