句法糖,恕我直言,通常使程序比从极简主义的原语集编码更易读,更容易理解。我并没有真正看到好的,经过深思熟虑的语法糖的缺点。为什么有些人基本上认为语法糖最多是多余的,最糟糕的是要避免哪些?
编辑:我不想命名,但是因为人们问,看起来像大多数C ++和Java程序员,坦率地说他们并不关心他们的语言完全没有语法糖。在很多情况下,他们不一定非常喜欢语言的其他部分足以使缺糖值得权衡,而是他们真的不关心。此外,Lisp程序员似乎对他们语言的奇怪符号感到骄傲(我不会将其称为语法,因为它在技术上并非如此),尽管在这种情况下,它更容易理解,因为它允许Lisp的元编程工具像它们一样强大。答案 0 :(得分:10)
句法糖导致分号癌症。 Alan Perlis
如果在没有参考背景的情况下进行推理,则很难推理出语法糖。有很多关于为什么“语法糖”好或坏的例子,如果没有语境,所有这些都没有意义。
你提到语法糖是好的,它使程序可读并且更容易理解......我可以反驳说,有时候,句法糖可以影响语言的正式结构,特别是当语法糖是一个后期附录时在编程语言的设计过程中。
我没有考虑语法糖,而是想用精心设计的语言来提高可读性和易于理解,以及设计不良的语言。
此致
答案 1 :(得分:9)
在某些情况下,句法糖会以令人不愉快的方式相互作用。
一些具体的例子:
第一个是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;
一个广泛使用的构造(以及一个本身具有bug范围的构造,因为如果你想改变使用i,你必须记得更新这两个变量)。但是,由于这很容易嵌入到其他表达式中,因此前缀和后缀的问题一直存在。 在for循环中使用时无关紧要,评估发生在任何其他评估之外,但在其他地方使用它可能会引起混淆(因为您可能正在嵌入计算的一个非常重要的方面(无论是当前还是下一个)应该使用一个非常小且容易错过的形式。
以上所有(除了编译器真正应该为你找到的锁/盒之外)是使用情况可能很好的情况,或者有经验的程序员可能会认为“这对我来说非常清楚”但是混淆的范围存在,当然对于新手程序员或那些采用不同语法的人来说。
答案 2 :(得分:8)
过多的不必要的糖只会增加语言的膨胀。我会说出名字,但之后我就会被焚烧。 :)此外,有时语言使用语法糖而不是真正的实现。例如,有一种语言应该保持无名,其“泛型实现”只是一层薄薄的语法糖。
答案 3 :(得分:5)
无意义。 C和Lisp程序员一直使用句法糖。
示例:
a[i]
代替*(a+i)
'(1 2 3)
代替(quote 1 2 3)
答案 4 :(得分:2)
请参阅Law of Leaky Abstractions - 太多的糖,你只是在不了解或不知道发生了什么的情况下使用它,这使得如果出现出错的话,调试越来越难。并不是说“语法糖”是一件坏事,只是许多程序员依赖它而没有真正意识到它们被屏蔽的东西,然后如果语法糖遇到问题则会被搞砸。
答案 5 :(得分:2)
就个人而言,我总是发现术语“语法糖”含糊不清。我的意思是,如果你想获得技术,除了基本算术之外的任何事情,if语句和goto都是语法糖。
我认为大多数人在解除“语法糖”时的意思是语言特征使得复杂过于简单。最臭名昭着的例子是Perl。但由于我不是Perl专家,我将举例说明我在python中所谈论的内容(取自this question):
reduce(list.__add__, map(lambda x: list(x), [mi.image_set.all() for mi in list_of_menuitems]))
这显然是为了让一些简单的事情变得可怕,可怕的错误。
这并不是说我会删除这些功能。我认为只需要仔细使用这些功能。
答案 6 :(得分:2)
我一直都理解“语法糖”来指代添加到现有语言中的任何语法,这些语法不会扩展语言的功能。否则,任何不如二进制机器语言直接的东西都可以被称为语法糖。
即使他们没有扩展语言的功能,它们仍然非常有用。
例如,LINQ是语法糖,因为它不会为C#3添加任何新功能,这些功能在C#2中是不可能的。但是要在C#2中执行与简单的LINQ表达式相同的操作,需要花费更多的代码来完成并且更难以阅读。
相反,泛型不是语法糖,因为你可以在C#2中用C#1做一些事情,比如创建一个可以包含任何值类型而不用拳击的集合类。
答案 7 :(得分:1)
可能是因为它会导致程序员感到困惑,他们不知道幕后真的发生了什么,这可能反过来导致一些效率低下或写得不好的代码。只是一个猜测,我不认为它是一个“坏事”也是。
答案 8 :(得分:1)
句法糖可以使你的程序更容易理解,或者更不容易理解。如果你为琐碎的东西添加语法糖,你只会增加认知负担,因为语言变得更加复杂。另一方面,如果你可以添加以某种方式完成的语法糖来确定一个特定的概念并突出它,那么你就可以获胜。
答案 9 :(得分:1)
语法通常会使语言难以学习,更不用说掌握了。因此,语法集越小,学习和尝试掌握就越容易。这是许多新语言从流行的现有语言中借用语法的主要原因。
另外,虽然我可以简单地避免学习某些我不感兴趣的功能,但我最终会发现自己正在阅读别人的代码 那样的功能然后我会需要学习该功能只是为了理解他们的代码。
答案 10 :(得分:0)
这是更多的打字和更多的抽象层。我更倾向于使用一种设计为具有更高抽象级别的语言,然后添加一种语法糖语言来模仿其他语言内置的功能。