14

恕我直言,语法糖通常使程序比从一组非常简约的原语进行编码更具可读性和更容易理解。我真的没有看到好的,深思熟虑的语法糖的缺点。为什么有些人基本上认为语法糖充其量是多余的,最坏的情况是应该避免的?

编辑:我不想说出名字,但自从人们问起,似乎大多数 C++ 和 Java 程序员,例如,坦率地说,他们并不关心他们的语言完全缺乏语法糖。在很多情况下,他们并不一定只是喜欢语言的其他部分就足以使缺少糖分值得权衡,而是他们真的不在乎。此外,Lisp 程序员似乎几乎为他们语言的奇怪符号感到自豪(我不会称它为语法,因为它在技术上不是),尽管在这种情况下,它更容易理解,因为它允许 Lisp 的元编程工具与它们一样强大。

4

11 回答 11

12

句法糖会导致分号癌。艾伦·佩利斯

如果在没有参考上下文的情况下进行推理,就很难对语法糖进行推理。有很多关于“语法糖”为什么好或坏的例子,没有上下文,所有这些都是毫无意义的。

你提到句法糖在使程序可读和更容易理解时是好的……我可以反驳说,有时句法糖会影响语言的形式结构,特别是当句法糖是设计过程中的后期附录时的一种编程语言。

与其从语法糖的角度思考,我更喜欢从设计良好的、促进可读性和易于理解的语言以及设计糟糕的语言的角度思考。

问候,

于 2009-02-13T21:24:26.277 回答
10

在某些情况下,语法糖会以令人不快的方式相互作用。

一些具体的例子:

第一个是 c#(或 java)特定的,自动装箱和锁/同步结构

private int i;
private object o = new object();

private void SomethingNeedingLocking(bool b)
{
    object lk = b ? i : o;
    lock (lk) { /* do something */ }
}

在这个例子中,可以使用任何对象作为同步点的有用的锁结构与自动装箱相结合,会导致一个可能的错误。每次都会对 i 的新盒装实例进行锁定。有争议的是,锁定结构过于有用,并且锁定的其他一些特定结构会更好,但肯定组合仍然存在缺陷。

多变量声明和指针:

long* first, second;

一个经典的错误(虽然很容易发现)。多个变量的糖不适合指针声明。

一些构造不需要糖的其他方面来引起问题,一个经典的例子是 ++ 运算符。它巧妙地让你避免写作

i = i + 1;

一种广泛使用的构造(并且它本身具有错误范围,因为如果您希望更改使用 i,则必须记住更新这两个变量)。然而,由于这很容易嵌入到其他表达式中,前缀和后缀的问题出现了。当在 for 循环中使用时,这无关紧要,评估发生在任何其他评估之外,但在其他地方使用它可能会造成混淆(因为您可能嵌入了计算的一个非常重要的方面(无论是当前还是下一个value 应该被使用) 变成一个非常小且容易遗漏的形式。

以上所有情况(编译器确实应该为您发现的锁/盒子除外)都是使用可能很好的情况,或者有经验的程序员可能会认为“这对我来说非常清楚”,但肯定存在混淆的范围对于新手程序员或转向不同语法的程序员。

于 2009-02-13T21:45:38.940 回答
9

太多不必要的糖只会增加语言的膨胀。我会说出名字,但我会被激怒。:) 另外,有时语言使用语法糖而不是真正的实现。例如,有一种语言将保持无名,其“泛型实现”只是一层薄薄的语法糖。

于 2009-02-13T21:19:28.130 回答
7

废话。C 和 Lisp 程序员一直都在使用语法糖。

例子:

  • a[i]代替*(a+i)
  • '(1 2 3)代替(quote 1 2 3)
于 2009-02-13T22:58:18.953 回答
4

一般来说,语法使一门语言难以学习,更不用说掌握了。因此,语法集越小,越容易学习和尝试掌握。这是许多新语言从流行的现有语言中借用语法的主要原因。

此外,虽然我可以简单地避免学习某些我出于某种原因不感兴趣的功能,但我最终会发现自己正在阅读喜欢该功能的其他人的代码,然后我需要去学习该功能只是为了理解他们代码。

于 2009-02-13T22:10:56.213 回答
3

就个人而言,我一直觉得“语法糖”这个词含糊不清。我的意思是,如果你想获得技术知识,除了基本算术、if 语句和 goto 之外的任何东西都是语法糖。

我认为大多数人在忽略“语法糖”时的意思是语言功能使复杂的东西变得过于简单。最臭名昭著的例子是 Perl。但由于我不是 Perl 专家,我会给你一个我在 python 中谈论的例子(取自这个问题):

reduce(list.__add__, map(lambda x: list(x), [mi.image_set.all() for mi in list_of_menuitems]))

这是一个明显的尝试,让更简单的事情变得可怕,可怕的错误。

这并不是说我支持删除这些功能。我认为这些功能只需要小心使用。

于 2009-02-13T21:36:29.743 回答
3

我一直将“语法糖”理解为是指添加到现有语言中但不扩展语言功能的任何语法。否则,任何比二进制机器语言更直接的东西都可以称为语法糖。

即使它们没有扩展语言的功能,它们仍然非常有用。

例如,LINQ 是语法糖,因为它没有向 C#3 添加任何在 C#2 中不可能实现的新功能。但是要在 C#2 中执行与简单的 LINQ 表达式相同的操作,将需要更多的代码来完成并且更难阅读。

相反,泛型不是语法糖,因为您可以在 C#2 中使用它们完成 C#1 无法做到的事情,例如创建一个可以包含任何值类型而无需装箱的集合类。

于 2009-02-13T22:47:09.403 回答
2

语法糖可以使您的程序更易于理解,也可以不那么容易理解。如果你为琐碎的事情添加语法糖,你只会增加认知负担,因为语言变得更加复杂。另一方面,如果您可以添加语法糖以某种方式完成以查明特定概念并突出显示它,那么您就可以获胜。

于 2009-02-13T21:19:21.377 回答
2

请参阅泄漏抽象定律- 太多的糖,你只是在不了解或不知道发生了什么的情况下使用它,如果出现问题,这使得调试变得越来越困难。与其说“语法糖”是一件坏事,不如说是很多程序员依赖它而没有真正意识到他们被屏蔽了什么,然后如果语法糖遇到问题,他们就搞砸了。

于 2009-02-13T21:35:39.200 回答
1

可能是因为它导致不知道幕后真正发生了什么的程序员感到困惑,这反过来又可能导致一些低效或编写不佳的代码。只是猜测,我不认为这是一件“坏事” “ 任何一个。

于 2009-02-13T21:17:01.880 回答
0

它是更多的类型和更多的抽象层。我更愿意使用一种设计为具有更高抽象级别的语言,然后是一种带有语法糖的语言,在模仿其他语言内置的功能方面做得很差。

于 2009-02-13T21:19:50.000 回答