编程语言应该严格还是宽松?[关闭]


14

在Python和JavaScript中,分号是可选的。

在PHP中,围绕数组键的引号是可选的($_GET[key]vs $_GET['key']),尽管如果省略它们,则会首先使用该名称查找常量。它还允许2种不同样式的块(用冒号或大括号分隔)。

我现在正在创建一种编程语言,并且试图确定我应该做的严格程度。在很多情况下,多余的字符不是真正必要的,并且由于优先级的原因可以明确地解释,但我想知道是否仍应强制使用它们以鼓励一致性。

你怎么看?


好的,我的语言不是花哨的模板语言,而是编程语言。HamlDjango模板之间的一种交叉。打算与我的C#Web框架一起使用,并且应该具有很好的可扩展性。


22
这是一场圣战的话题。

1
Pythonista鼓励使用分号。坦白说,我不确定是否完全需要它们-仅允许每行多条语句,而这完全可以避免,而不会造成麻烦。所以...我赞成使用更严格的语言。但是,有时您可以使用诸如StyleCop之类的代码分析工具来强制执行某种语言之外的功能。
工作

1
PHP数组键的引号不是可选的。它们在PHP2中,但是后来的版本会自动定义常量。但是,在基本字符串插值中不允许使用它们"..$_GET[raw].."
mario'2

1
@Ralph:规则有点复杂。书写是正确的"xx$_GET[raw]xx"-如果您开始使用花括号,则该键必须用"xx{$_GET['raw']}xx"引号引起来。如果使用花括号,则普通的PHP解析器将对其进行检查,并采用严格的语法。仅仅是"$_GET[x]"因为密钥被视为原始字符串,这也是一个严格的规则,PHP会解析on上的错误"$_GET['x']"
mario

2
@mario:事实上,我们甚至都在进行对话,这意味着在处理数组键的方式上存在一些歧义和困惑。似乎在字符串内部,它是明确的但不一致的(如果已经在字符串中,则不能使用引号,除非使用花括号,否则必须这样做,但应该在外部)。和外部字符串一样,在“普通” PHP中...这样,它确实很奇怪。
mpen 2011年

Answers:


19

不同类型的语言有不同的用途,因此该问题的答案实际上取决于您要使用它的目的。

例如,Perl是一种非常宽松的语言,我发现它对于编写快速修正或数字运算脚本非常有用。对于坚固可靠的项目,我使用C#。

您需要为目标使用量获取合适的余额。它越严格,编写代码所需的时间就越长,但是您将获得更高的鲁棒性,可重用性,并且易于维护。


26

我在编程语言(而不是脚本语言)中寻找的是一致性和强类型。

在当前的编程语言中,可以在某些地方省略分号而不会变得模棱两可({}块中的最后一个表达式是一个)。如果在这种情况下,编程语言允许您省略字符,那么程序员现在会遇到其他问题。现在,除了通用语言语法外,她还必须知道在什么情况下也可以省略语法的某些部分。

这些额外的知识对于编写代码的程序员来说不是问题,但是对于以后不得不解释现有代码(包括一段时间后的原始作者)的任何人来说,这都是一个负担。

key在相同的上下文中添加常量时,您的PHP示例打开了程序中细微错误的可能性。编译器无法知道这不是什么意思,因此问题只会在运行时而不是编译时变得明显。


1
同意,您应该限制开发人员的可能性:更多的可能性=>需要思考更多(我应该这样还是那样进行)=>更少的时间来进行实际工作
Kemoda 2011年

我看不到缺少隐式类型转换与语言语法之间的关系。
dan_waterworth 2012年

5
另外,当您阅读时,$_GET[key]您一无所知。您最终只是对整个项目进行了grep操作,只是为了知道是否key为常数。这样可以节省0.5秒钟的写入时间,而需要20秒钟的读取时间。
Moshe Revah

如果您的语言为您提供了无区别的选择,则无论是否编码,编码风格都倾向于其中一种标准化...
Deduplicator

11

在每个有歧义的地方,编译器都需要某种方式来猜测程序员的真正含义。每次发生这种情况时,程序员都有机会真正表达不同的意思,但并没有降低歧义解决规则。

编写逻辑上正确的代码已经足够困难了。表面上添加语法上的歧义似乎是“友好的”,但这是公开邀请将新的,意想不到的,难以调试的错误引入代码库。底线是,尽可能严格。

在您的示例中,您提到分号在Python和JavaScript中是可选的。至少对于Javascript,这并非完全正确。分号与其他C族语言一样,在JS中也是如此。但是语言规范要求JavaScript解析器在某些情况下插入缺少的分号。人们普遍认为这是一件非常糟糕的事情,因为它容易使您的意图出错并弄乱您的代码。


6

您应该使自己的语言变得多么宽松的答案与得克萨斯州口音中所说的问题的答案相同:“朋克,您感觉有多幸运?”。


我不明白
mpen 2011年

4
我开玩笑的不好的尝试是,随着系统的发展,动态类型可能会咬住您,尤其是在添加经验不足的开发人员的情况下。以我的经验,任何价值的系统都将变得越来越大,并且越来越多的开发人员正在开发它们。这样,“查找符号的所有用法”或“全部重命名”或“安全删除”或“查找解决方案中的错误”绝对是非常宝贵的。在有限的意义上,VB是后期绑定的,并且具有广泛的类型强制性,因此动态类型在当前的演出中造成了许多错误。
亨里克

好吧,如果您对自己的项目感到幸运,例如幸运的是拥有优秀和经验丰富的开发人员,或者幸运的是编写了正确的代码;您可以使用动态类型。
亨里克

2
啊...但是这个问题从来没有真正涉及到动态类型:)
mpen

1
啊,是真的Raplh。我只是倾向于认为动态语言比通常更松散。你说得对。
亨里克

4

如果语言没有太多变化,则每个人都不必为编码的一致性而付出如此努力。当用户发出不必要地增加复杂性的请求时,我们不喜欢它,那么为什么要问我们的开发语言呢?


+1:我完全同意。我不明白为什么KISS和YAGNI之类的原则不应应用于语言设计。
乔治(Giorgio)

2

我个人的喜好是能够具有足够的严格度来捕捉我的错字,但又要尽可能减少额外的样板。我在http://www.perlmonks.org/?node_id=755790上讨论了这个问题。

也就是说,您正在为自己设计语言。您应该使它成为您想要的样子。


+1:...具有足够的严格度来捕捉我的错字的能力,但要尽可能减少多余的样板。-是的 您是否熟悉Anders Hejlsberg的C#计划?他正在做出有意识的决定,以强调“精于礼”。channel9.msdn.com/Blogs/matthijs/...
吉姆·G.

@ jim-g:感谢您的想法。我对C#的任何内容都不熟悉。我已经在微软界工作了很多年了。
btilly 2011年

1

我喜欢我的语言按照我的意思去做。通常,这很容易趋向于宽松。我还希望能够在元素或块上标记“ strict”,以便能够调试/分析该有限区域。


1

我通常倾向于落在“什么将使我作为程序员更容易”这一方面。当然,这可能意味着不止一件事。在Javascript中,几乎没有类型检查,这在您遇到怪异的错误之前非常有用。另一方面,在Haskell中,有很多类型检查,这使更多的工作提前完成,但掩盖了某些类的bug。

老实说,我会检查一堆语言以了解它们的作用,并尝试找到一种没有它们能打中的利基市场!

我认为没有明显的正确方法,或者至少在尚无共识的情况下。因此,通过创建具有不同类型系统的语言,我们正在学习。

祝好运。


1

我建议一种好的编程语言应该有严格的规则,应该期望这些实现能够一致地执行,但是规则应该以这样的方式编写,以便有所帮助。我将进一步建议,应该考虑设计一种语言,以避免在两个完全不同的程序之间的“汉明距离”仅仅是一个的情况。显然,用数字或字符串文字无法实现这样的目标(如果用123代替1223或13的程序员表示,编译器可能不太了解程序的含义)。另一方面,如果将语言:=用于赋值和==相等性比较,而不使用单个语言= 出于任何法律目的,那么这将大大减少被认为是比较的偶然作业和被认为是偶然的虚无比较的可能性。

我建议,尽管在某些地方编译器可以用来推断事物,但这种推断通常在最简单的情况下最有价值,而在较复杂的情况下则不那么有价值。例如,允许替换:

  字典<complicatedType1,complicatedType2> item =
    new字典<complicatedType1,complexType2()>;

  var item = new字典<complicatedType1,complexType2()>;

不需要任何复杂的类型推断,但是可以使代码的可读性大大提高(此外,仅在需要使用场景的情况下使用更详细的语法,例如,因为存储位置的类型与表达式的类型不完全匹配)创建它,将有助于引起人们对可能需要它的地方的更多关注)。

尝试更复杂的类型推断的一个主要困难是可能会出现模棱两可的情况。我建议一种好的语言应允许程序员将信息包含到编译器中,从而可以用来解决此类歧义(例如,通过将某些类型转换视为对其他类型转换的偏好),确定它们无关紧要(例如,即使有两种可能重载可能会执行不同的代码,程序员已指出,在可能使用其中任何一种的情况下,它们的行为应相同),或标记(或仅使用)上述两种方法均无法处理的那些。


1

对我来说,可读性是最重要的。

对于熟悉该语言的人来说,应该清楚代码片段的含义,而不必深入分析上下文。

该语言应该能够尽可能经常地标记错误。如果每个随机字符序列都构成了语法正确的程序,那将没有帮助。如果变量自动创建使用它们的第一次,然后拼错client因为cleint不会给你一个编译错误。

除了语法之外,该语言还应具有明确定义的语义,也许这比决定一个体面的语法还要难...

很好的例子:

  • 在Java中,"1"是一个字符串,1一个int,1.0一个double和1L一个long。一看便知道那是什么。

  • 在Java中,=是赋值。它为基本类型分配值,为引用类型分配引用。它永远不会复制或比较复杂的数据。

  • 在Java中,调用方法需要括号,而这种方法与变量显然有所区别-因此,如果没有括号,则无需搜索方法定义,它只是读取数据。

错误的例子:

  • 在Java中,类似这样的符号client几乎可以是任何东西:包路径元素,类或接口名称,内部类名称,字段名称,方法名称,局部变量,甚至更多。由用户决定是否引入或遵守命名约定。

  • 在Java中,点.被过度使用。它可以是包名称中的分隔符,包和类之间的分隔符,外部类和内部类之间的分隔符,实例表达式和要在实例上调用的方法之间的连接符,等等。

  • 在许多语言中,if块的花括号是可选的,如果有人向(实际上不存在的)块添加了另一条语句,则会导致讨厌的错误。

  • 中缀运算符:有时我不得不停步于数字表达式,然后逐步思考它的含义。我们都习惯用infix表示法来编写数学表达式a * b / c * d + e。大多数时候,我们都记得乘法和除法比加法和减法优先(但是您是否意识到我们不是在除以c*d,而是仅除以c然后乘以d?)。但是,还有许多其他的中缀运算符具有自己的优先级规则,并且在某些语言中超载,因此很难跟踪。也许强制使用括号是更好的方法。


您几乎已经讨论过歧义性,但是在不产生歧义性的情况下,可以有多种方式来做同一件事。也许我们可以有两个乘法运算符,*×。无论5*3和5×3`意味着同样的事情,和有经验的程序员确切知道他们的意思,而无需环顾周围的环境。但是,问题在于,现在有两种方法可以做同一件事,并且整个程序中可能有人在它们之间进行交换。我相信这是我问这个问题时更加担心的事情。
mpen

-2

您可能会考虑使用自然语言进行类比。在电子邮件中,您是语法纳粹吗?或者您可以接受一些语法错误,例如不定式拆分,连词缺失或修饰符放错位置。答案归结为个人喜好。

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.