有很多编程语言受C风格语法(花括号,半音等)的影响很大,可能比任何其他语法风格更多.直到今天,许多现代的,成功的甚至是新发明的语言都使用这种语法 - 只需要考虑Java,C++,C#,PHP,JavaScript,C,Perl等.
有没有任何客观原因可以解释这种语法的巨大传播和成功?其他语言的语法是否有某些优势?
Mei*_*bur 15
恕我直言,唯一使C风格语法流行的是大多数人都知道它.因此,使用C风格的新语言可以应用旧的habbits(如命名约定).这是件好事!虽然我认为,语法是学习新语言最不重要的.但是一个好的语法可以帮助避免错误.
微软做了很多努力使VB.NET和C#一样重要(记住MSDN中的所有" null(在Visual Basic中都没有)",这让我非常恼火),但C#仍然是.NET平台的主要语言.似乎VB.NET的前辈声誉不好.而且,使用C风格似乎更具专业外观.
毕竟,C的设计目标之一是使编译器易于实现.使用预处理器比为常量定义新的语言构造更容易.或者[5]的语义.这不适用于C++,这很难实现,部分原因是它试图与C保持兼容.
例子:
编辑:另一个很好的例子:C#或.NET中最糟糕的问题是什么?.但是,当然,一旦你习惯了它并在IDE的帮助下,这不再是一个问题,有时甚至更自然,因为它更像计算机的实际工作方式.
运算符优先级
=
分配和==
比较.if (a = b)
任何人?类似的,&&
和&
,||
和|
,(!
和~
)在语法上太接近了,尽管它们意味着不同的东西.就个人而言,我更喜欢and
和or
,因为符号应该只支持语法而不是主要部分.
++
和--
运营商; 使一些语句稍微短一些,但会为表达式(a = b+++b++
)引入副作用.最初,编译器可以更有效地编译它i = i + 1
.
for(init;condition;step)
环; 虽然最佳做法是仅使用它来增加变量,但是没有明确的语法.相反,这对于构造而言是多余的,因为它(几乎)相同
init;
while (condition) {
statement;
step;
}
Run Code Online (Sandbox Code Playgroud)switch
声明; 曾经忘了休息吗?为什么不像大多数其他语言那样允许范围作为案例标签?
if(condition)
声明.使用括号不是一个好的选择,因为它可以在条件表达式本身中使用:
if (!(var & 0x02))
Run Code Online (Sandbox Code Playgroud)预处理器
牙套.这是有争议的.我不同意那些声称这些"不要使用大量屏幕空间"的论点,更简洁或写得更快.首先,应该将语言设计为易于阅读,不易编写.其次,根据您的风格,大括号使用的屏幕空间大小与关键字完全相同:您可以将它们写在一行中.是不是浪费了很多空间?
此外,人们批评LISP的括号混乱.从来没有发生过你必须计算你的大括号,找出你错过了哪一个?我有时会在结束括号后添加注释,以指示应该在这里结束的内容.BASIC语法已包含此功能.并且甚至不需要相当于一个开口支架.部分我同意牙箍是好的:它们几乎是不可见的,并且凹痕是主要的视觉特征.看到这种方式,python是下一步.
分号作为语句终止符或分隔符.为什么单个分号是有效的声明?
if (condition);
DoSomething();
Run Code Online (Sandbox Code Playgroud)无法区分的关键字序列
public static string main()
Run Code Online (Sandbox Code Playgroud)
这是方法声明吗?还是变量声明?还是功能原型?或者是其他东西?例如,一些标点符号(以及每种声明类型的关键字)可以帮助明确区分返回类型.这就是使C++难以解析的原因.
正交性.{} while (condition)
确实适合其他语言结构,其中语句后面跟着该语句.我认为是VB的
do [while/until condition]
Statements
loop [while/until condition]
Run Code Online (Sandbox Code Playgroud)
一个很好的解决方案,因为你有4种不同语义的可能组合:在do/loop关键字之后/之后.
变量类型修饰符的奇怪顺序.
int * const & i [];
Run Code Online (Sandbox Code Playgroud)类型和变量名称只是在彼此之后出现,没有标记它是局部变量声明.Scala使用val和var do表示final/mutable变量的声明,类型用冒号分隔.在大多数其他事情上,Scala使用Java语法.
赋值运算符返回值; 语句(带效果)和表达式(只返回值)之间没有区别
编辑:这里有更多的例子:https://stackoverflow.com/questions/163026/what-is-your-least-favorite-syntax-gotcha
你当然不会就这些问题达成一致意见,并不是所有这些都必然是否定的(例如,分号),或者我知道的解决方案对所有情况都更好.即使我愿意,结果语言也不会是完美的语言.编程语言将不断发展,新发明的语言有望从其前辈中学习.那么,为什么不保持一种已知的语法而不是每十年设计一个新语法呢?
但是,当语言设计人员有可能避免编程错误时,只是输入错误,为什么不改变呢?例如,这是在C#的switch语句中完成的,它使break(或goto)成为必需的.一旦消除了最严重的缺点,大多数程序员知道其余语法语法的好处远远超过了从头开始重新设计语言的优势.但我仍然感到惊讶的是,为什么这么多程序员仍然如此急切地捍卫C语法,尽管这些已经习惯了计算机科学的进步需要定期修改几乎所有内容.
总而言之,我认为C语法占主导地位的唯一原因是几乎所有专业程序员都知道,这些只是习惯了它.虽然其他语言可能具有优势,但实际语法不太重要.这与电气工程师原样使用电荷惯例的原因相同.
(也许会有一个关于程序员访问Dennis Ritchie的漫画:"请不要在switch语句中选择休息!")
在我看来,实际上只有三个主要的语法元素从 C 传播到世界其他地方:用花括号表示的块,表示行尾的分号,以及一般的“简洁”风格。
用单个字符包装块是合理的;首先,它打字速度很快,不占用大量屏幕空间(与 BEGIN-END 关键字对不同)。其次,语法相当灵活,因此您可以在特殊情况下根据需要/想要格式化块(在 Python 之类的东西中您无法真正做到这一点。)就像电子邮件客户端一样,并且仍然可以被人类和编译器读取(这是我在使用 python 样式的 indents-for-blocks 时遇到的唯一真正问题)。
不过,为什么要花括号呢?我不知道在 C(或更可能是 BCPL)中使用它们的历史先例是什么,但我可以冒险猜测。“标准”美式键盘上没有那么多配对符号:{} [] () 和 <> 就是关于它的。如果我们想让编译器的工作更轻松,我们需要 BEGIN 和 END 的唯一符号,因此使用类似 | 或 # 表示块结束。在我们的对中,{} 确实是唯一一个还没有意义的对 - () 和 [] 都有很多数学包袱(它或多或少地直接用函数和数组进行翻译)并且 < 和 > 都表示各种事情。我也会为块选择 {}。
对于一种新语言,如果您不使用关键字或缩进,为什么要更改它?许多程序员习惯于使用它们来表示块,为什么要使所有肌肉记忆无效?
使用分号也是同样的道理。使用一些东西来表示一行的结尾会让编译器的工作变得更容易。只使用一个字符可以让程序员的生活变得更轻松。扫描键盘上的单个字符,从数学上讲,分号是少数几个意义不大的字符之一。从英语语法的角度来看,句号(或者逗号)最有意义,但它们已经被用作小数点。而且,如果你眯起眼睛,将分号作为行终止符的含义与英语中的含义相当相似。再说一次,如果你要开始一门新语言,为什么要改变它?
至于基本的简洁性,我认为这是唯一可以客观地说是一个好主意的想法。我可以输入的字符越少,以将想法传达给计算机,同时仍然足够接近英语以阅读,就越好。
(您可能会争辩说,大多数 C 类型语言也借用了大部分关键字词汇,但实际上,C 的大多数关键字都来自诸如 ALGOL、FORTRAN 和 BCPL 之类的旧语言,而且实际上 - 它们(大部分)都是常识。再说一次,一旦您对编程社区进行了培训,“while 循环”是什么,为什么要更改名称?)
我认为今天任何不使用像 C 那样的语法的语言都是因为一些基本的范式转变(比如 Python 的缩进方法)。如果你正在开发一种工作方式基本相同的语言,为什么要改变什么?您的目标受众已经可以用他们的小指敲击花括号键,为什么要让这项特殊技能毫无价值?
或者,将最后一句话更进一步,如果您想通过改变游戏规则的新语言(Java、C# 等)向编程社区推销,如果您的客户都已经知道语法。