Scala的动机强调了形式语言理论和良好风格?

时间:2014-09-10 10:45:15

标签: scala functional-programming programming-languages

为什么许多人说在Scala中使用下划线是良好做法并使您的代码更易于阅读?他们说动机来自形式语言理论。然而,许多程序员,特别是来自其他语言的程序员,尤其是那些具有匿名功能的程序员,更喜欢不使用下划线,尤其是占位符。

那么下划线的重点是什么?为什么Scala(和om-nom-nom指出的其他一些函数式语言)有下划线?在复杂性和语言理论方面,正式基础是什么,为什么它常常好的风格来使用它?

1 个答案:

答案 0 :(得分:21)

语言学

Scala中大多数下划线用法的起源和动机是允许一个人构造表达式和声明,而不需要总是给出每个变量(我的意思是"变量"如谓词微积分,而不是编程)语言的名称。我们一直在自然语言中使用这个,例如我在这句话的前一句中使用"这个"我用"这个"提到了这句话。没有任何混淆我的意思。在自然语言中,这些词通常被称为" 代词"," anaphors "," cataphors ",所指对象" 先行"或" postcedent ",理解/解除引用它们的过程称为" anaphora "。

算法信息理论

如果我们必须说出每件事情的话。在自然语言之前,我们可以参考它,类似于每种类型的东西,以便量化它,如在谓词微积分和大多数编程语言中,然后说话将变得非常漫长。感谢上下文,我们可以推断出像&#34;这&#34;,&#34;它&#34;,&#34;&#34;等等,我们可以轻松地做到这一点。< / p>

因此,为什么要限制这种简单,优雅和有效的方式与自然语言沟通?所以它被添加到Scala。

如果我们确实试图将每一件事命名为&#39;或者&#39;类型的东西&#39;,句子变得如此漫长和复杂,以至于由于它的冗长和引入冗余符号而变得非常难以理解。你添加到句子中的符号越多,理解就越难理解,这就是为什么它不仅在自然语言中的优秀实践,而且在Scala中也是如此。实际上,人们可以用Kolmogorov复杂性来形式化这个断言,并证明采用占位符的句子序列的复杂性低于不必要地命名所有内容的句子(除非名称在每种情况下都完全相同,但通常不会合理)。因此,我们可以确定地说,与一些程序员相信,占位符语法更简单,更易于阅读

它在使用中有一些阻力的原因是,如果一个人已经是程序员,就必须努力重新训练大脑而不是命名一切,就像(如果他们能记住)他们一样可能已经发现学习编码首先需要付出相当大的努力。

实施例

现在让我们更正式地看一些特定用途:

占位符语法

意味着&#34;它&#34;,&#34;他们&#34;,&#34;&#34;,&#34;他们的&#34;等(即代词),例如1

lines.map(_.length)

可以理解为&#34;将行映射到他们的长度&#34;同样我们可以将lineOption.map(_.length)读作&#34;将该行映射到 it&# 39; s 长度&#34;。就复杂性理论而言,对于每一行,比<&strong>更简单。在行中,取“&#39; line&#39;&#34; - 这将是lines.map(line => line.length)

也可以读作&#34;&#34; (定冠词)与类型注释一起使用时,例如

(_: Int) + 1

&#34;在 整数&#34;

中添加1

存在类型

某种类型的手段&#34;&#34; (&#34;一些&#34;代词),例如

foo: Option[_]

表示&#34; foo是某种类型的选项 &#34;。

更高的Kinded类型参数

同样,基本上意味着某种类型的&#34;&#34; (&#34;一些&#34;代名词),例如

class A[K[_],T](a: K[T])

可以阅读&#34; A类需要一些某种类型的K ...&#34;

模式匹配通配符

意味着&#34;任何事情&#34;或者&#34;无论什么&#34; (代词),例如

case Foo(_) => "hello"

可以读作&#34;对于包含任何内容的Foo,返回&#39; hello&#39;&#34;或者&#34;对于包含任何内容的Foo,返回&#39;你好&#39 ;&#34;

导入通配符

意味着&#34;一切&#34; (代词),例如

import foo._

可以读作&#34;从foo&#34;。

导入所有内容

默认值

现在我读到了这个&#34; a&#34; (不定冠词),例如

val wine: RedWine = _

&#34;给我一杯红酒&#34;,服务员应该把房子给你红色。

下划线的其他用途

下划线的其他用途与本Q&amp; A的要点并不完全相关,但我们对它们进行了简单的讨论

忽略值/参数/提取

允许我们忽略明确的模式安全&#39;办法。 E.g。

val (x, _) = getMyPoint

说我们不打算使用第二个坐标,所以当你无法在代码中找到它时,不需要变得怪异。

导入隐藏

只是说&#34;除了&#34; (介词)。

功能应用

E.g。

val f: String => Unit = println _

这是一个有趣的,因为它在语言学上有一个确切的类比,即名词化,&#34;使用动词,形容词或副词作为名词短语的头部,有无形态转换&#34; - 维基百科。更简单的是,将动词形容词转换为名词

在特殊方法名称中使用

纯粹是一种语法,与语言学无关。