斯卡拉的动机强调了形式语言理论和良好的风格? [英] Motivation for Scala underscore in terms of formal language theory and good style?

查看:174
本文介绍了斯卡拉的动机强调了形式语言理论和良好的风格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么很多人都说在Scala中使用下划线是一种很好的练习,并使代码更易于阅读?他们说动机来自形式语言理论。尽管如此,许多程序员,特别是来自其他语言的程序员,特别是那些具有匿名函数的程序员,更喜欢不使用下划线来特别用于占位符。

那么下划线有什么意义呢?为什么Scala(以及om-nom-nom指出的其他一些函数式语言)具有下划线?在复杂性和语言理论方面,什么是形式化基础,以及它为什么经常使用它的好风格?



大多数Scala下划线用法的起源和动机是允许一个构造表达式和声明,而不需要总是给这个语言的每个变量(我的意思是谓词变量中的变量,而不是编程中)。我们一直在自然语言中使用它,例如,我在这个句子中的前一句中使用this提到了一个概念,我用这个this来提到这个句子,而不会对我的意思产生任何混淆。在自然语言中,这些词通常被称为代词 anaphors cataphors strong>或 postcedent ,并且理解/解引用它们的过程称为回指

算法信息理论



如果我们必须在自然语言中指定每个事物,然后才能参考它,类似地每种类型的事物都要量化,就像在Predicate Calculus和大多数编程语言中一样,那么说话就会变得非常漫长。这要归功于我们可以推断this,it,that等词语的含义,因为我们很容易做到。因此,

为什么要限制这种简单,优雅和高效的方式与自然语言交流?所以它被添加到Scala中。



如果我们试图命名每一个'事物'或'类型的东西',句子变得如此漫长而复杂,由于冗长而引入冗余符号,难以理解。您添加到句子中的符号越多,就越难理解,这就是为什么它是良好的习惯,不仅在自然语言中,而且在斯卡拉也是如此。事实上,人们可以用Kolmogorov复杂度来形式化这个断言,并且证明采用占位符的句子序列比那些不必要地命名所有内容的句子复杂得多(除非名称在每个实例中完全相同,但通常没有意义)。因此,我们可以肯定地说与一些程序员的观点相反,即占位符语法更简单,更易读

它之所以有一些如果一个人已经是程序员,就必须努力重新训练大脑,而不是对所有事物进行命名,就像(如果他们记得的话)他们可能已经发现学习首先需要编码努力。

示例



现在让我们更正式地看一些具体用法:



占位符语法



意思是it,them,that,their即代词),例如1

  lines.map(_。length)

可以读作将长度映射到长度,同样我们可以读取 lineOption.map(_。length)为将该行映射到它的长度。在复杂性理论方面,这个比线条中的每个'line'简单,取'line'的长度 - 这将是 lines.map(line = > line.length)



与类型注释一起使用时,也可以读作the(定冠词) p>

 (_:Int)+ 1 

将1加到整数



存在类型



表示某种类型(某些代词),例如

  foo:Option [_] 

表示foo是某种类型的Option

较高的金型参数

一些类型(一些代词),例如:

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

可以读取class A需要某些类型的K ...



模式匹配通配符



表示任何或任何(代词),例如

  case Foo(_)=> hello

可以理解为对于包含任何内容的Foo,返回'hello'或for a Foo contains anything,return'hello'



导入通配符



意思是一切(代词),例如

  import foo._ 

可以理解为从foo导入所有内容。

默认值

现在我读到这个a(不定冠词),例如

  val wine:RedWine = _ 



给我一瓶红酒,服务员应该给你房子红色。



下划线的其他用途



下划线的其他用途并不真正相关到这个Q& A的时候,尽管如此,我们还是很少讨论它们。
$ b $ p忽略的值/参数/提取



允许我们以明确的模式安全方式忽略事物。例如

  val(x,_)= getMyPoint 

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



导入隐藏



只是说except(介词)的一种方式。

函数应用程序

例如

  val f:String => Unit = println _ 

这很有趣,因为它在语言学上具有精确的类比,即名词化,使用动词,形容词或副词作为名词短语的头部,有或没有形态转换 - 维基百科。更简单的说,它是将动词形容词转换成名词的过程。

在特殊方法名称中使用



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

Why is it that many people say that using underscore is good practice in Scala and makes your code more readable? They say the motivation comes from formal language theory. Nevertheless many programmers, particularly from other languages, especially those that have anonymous functions, prefer not to use underscores particularly for placeholders.

So what is the point in the underscore? Why does Scala (and some other functional languages as pointed by om-nom-nom) have the underscore? And what is the formal underpinning, in terms of complexity and language theory, as to why it often good style to use it?

解决方案

Linguistics

The origin and motivation for most of the underscore uses in Scala is to allow one to construct expressions and declarations without the need to always give every variable (I mean "variable" as in Predicate Calculus, not in programming) of the language a name. We use this all the time in Natural Language, for example I referred to a concept in the previous sentence in this sentence using "this" and I referred to this sentence using "this" without there being any confusion over what I mean. In Natural Language these words are usually called "pronouns", "anaphors", "cataphors", the referents "antecedent" or "postcedent", and the process of understanding/dereferencing them is called "anaphora".

Algorithmic Information Theory

If we had to name every 'thing' in Natural Language before we can refer to it, similarly every type of thing in order to quantify over it, as in Predicate Calculus and in most programming languages, then speaking would become extremely long winded. It is thanks to context that we can infer what is meant by words like "this", "it", "that", etc, we do it easily.

Therefore why restrict this simple, elegant and efficient means to communicate to Natural Language? So it was added to Scala.

If we did attempt to name every single 'thing' or 'type of thing', sentences become so long and complicated that it becomes very difficult to understand due to it's verbosity and the introduction of redundant symbols. The more symbols you add to a sentence the more difficult it becomes to understand, ergo this is why it's good practice, not only in Natural Language, but in Scala too. In fact one could formalize this assertion in terms of Kolmogorov Complexity and prove that a sequence of sentences adopting placeholders have lower complexity than those that unnecessarily name everything (unless the name is exactly the same in every instance, but that usually doesn't make sense). Therefore we can conclusively say contrary to some programmers belief, that the placeholder syntax is simpler and easier to read.

The reason why it has some resistance in it's use, is that if one is already a programmer, one must make an effort to retrain the brain not to name everything, just as (if they can remember) they may have found learning to code in the first place required quite an effort.

Examples

Now let's look at some specific uses more formally:

Placeholder Syntax

Means "it", "them", "that", "their" etc (i.e. pronouns), e.g. 1

lines.map(_.length)

can be read as "map lines to their length", similarly we can read lineOption.map(_.length) as "map the line to it's length". In terms of complexity theory, this is simpler than "for each 'line' in lines, take the length of 'line'" - which would be lines.map(line => line.length).

Can also be read as "the" (definite article) when used with type annotation, e.g.

(_: Int) + 1

"Add 1 to the integer"

Existential Types

Means "of some type" ("some" the pronoun), e.g

foo: Option[_]

means "foo is an Option of some type".

Higher Kinded type parameters

Again, basically means "of some type" ("some" the pronoun), e.g.

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

Can be read "class A takes some K of some type ..."

Pattern Match Wildcards

Means "anything" or "whatever" (pronouns), e.g.

case Foo(_) => "hello"

can be read as "for a Foo containing anything, return 'hello'", or "for a Foo containing whatever, return 'hello'"

Import Wildcards

Means "everything" (pronoun), e.g.

import foo._

can be read as "import everything from foo".

Default Values

Now I read this like "a" (indefinite article), e.g.

val wine: RedWine = _

"Give me a red wine", the waiter should give you the house red.

Other uses of underscore

The other uses of underscores are not really related to the point of this Q&A, nevertheless we breifly discuss them

Ignored Values/Params/Extractions

Allow us to ignore things in an explicit 'pattern safe' way. E.g.

val (x, _) = getMyPoint

Says, we are not going to use the second coordinate, so no need to get freaky when you cant find a use in the code.

Import Hidding

Just a way to say "except" (preposition).

Function Application

E.g.

val f: String => Unit = println _

This is an interesting one as it has an exact analogue in linguistics, namely nominalization, "the use of a verb, an adjective, or an adverb as the head of a noun phrase, with or without morphological transformation" - wikipedia. More simply it is the process of turning verbs or adjectives into nouns.

Use in special method names

Purely a syntax thing and doesn't really relate to linguistics.

这篇关于斯卡拉的动机强调了形式语言理论和良好的风格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆