【问题标题】:Objective advantages of C-style syntaxC 风格语法的客观优势
【发布时间】:2009-05-16 11:29:07
【问题描述】:

有大量的编程语言受到 C 风格语法(花括号、分号等)的严重影响,可能比任何其他语法风格都多。直到今天,许多现代、成功甚至新发明的语言都使用这种语法——想想 Java、C++、C#、PHP、JavaScript、C、Perl 等。

是否有任何客观原因可以解释这种语法的广泛传播和成功?与其他语言的语法相比是否有某些优势?

【问题讨论】:

    标签: c syntax


    【解决方案1】:

    恕我直言,使 C 风格语法流行的唯一原因是大多数人都知道它。因此,将 C 风格用于新语言可以应用旧习惯(如命名约定)。这是一件好事!尽管我认为,语法是学习一门新语言最不关心的问题。但良好的语法有助于避免错误。

    Microsoft 为使 VB.NET 与 C# 一样重要(记住 MSDN 中的所有“null(Visual Basic 中的Nothing)”做了很多努力,其中很烦我),但 C# 仍然是 .NET 平台的主要语言。似乎 VB.NET 对其前辈的坏名声有问题。而且,使用 C 风格似乎更专业。

    毕竟,C 的设计目标之一是使编译器易于实现。使用预处理器比为常量定义新的语言结构更容易。或者 a[5] 的语义。这不适用于很难实现的 C++,部分原因是它试图与 C 保持兼容。

    例子:

    • 区分大小写,尽管不区分大小写对人类来说更为自然(对计算机而言并非如此)。这并不意味着您应该以不同于声明的方式拼写标识符(当心!),但可能会导致混淆。实际示例 (Java):getWhiteSpace() 或 getWhitespace()?

    编辑: 另一个很好的例子:What is the worst gotcha in C# or .NET?。 但是,当然,一旦您习惯了它并在 IDE 的帮助下,这不再是什么大问题,有时甚至更自然,因为它更类似于计算机的实际工作方式。

    • 运算符优先级

    • = 用于分配,== 用于比较。 if (a = b) 有人吗?类似地,&&&|||、(!~)在语法上过于接近,尽管它们的含义不同。就个人而言,我更喜欢andor,因为符号应该只支持语法而不是主要部分。

    • ++-- 运算符;使一些语句稍微短一点,但会给表达式带来副作用 (a = b+++b++)。最初,编译器可以比i = i + 1 更有效地编译它。

    • for(init;condition;step) 循环;尽管最佳实践是仅使用它来增加变量,但对此不存在显式语法。相反,这个 for 构造是多余的,因为它(几乎)与

      相同
      init;
      while (condition) {
        statement;
        step;
      }
      
    • switch 声明;有没有忘记休息?为什么不像大多数其他语言那样允许范围作为大小写标签?

    • if(condition) 声明。使用括号并不是一个好的选择,因为它可以在条件表达式本身中使用:

      if (!(var & 0x02))
      
    • 预处理器

    • 大括号。这是有争议的。我不同意这样的论点,即这些“不使用大量屏幕空间”、更简洁或写起来更快。首先,语言应该被设计成易于阅读,而不是易于书写。其次,根据您的风格,大括号使用的屏幕空间与关键字完全相同:您将它们写在一行中。是不是太浪费空间了?

      此外,人们批评 LISP 的括号杂乱无章。你从来没有发生过你必须数数你的牙套才能找出你漏掉的地方吗?我有时会在右大括号后添加注释以指示应该在此处结束的内容。 BASIC 语法已经包含了这个。甚至不需要一个相当于一个开口大括号。 我部分同意大括号是好的:它们几乎看不见,缩进是主要的视觉特征。这样看来,python就是下一步了。

    • 分号作为语句终止符或分隔符。为什么单个分号是有效语句?

      if (condition);
        DoSomething();
      
    • 难以区分的关键字序列

      public static string main()
      

      是方法声明吗?还是变量声明?还是函数原型?或者是其他东西?一些标点符号(以及每种声明类型的关键字)在这里可能会有所帮助,例如,明确区分返回类型。这就是 C++ 难以解析的原因。

    • 正交性。 {} while (condition) 确实适合语句后跟块的其他语言结构。我认为是VB的

      do [while/until condition]
        Statements
      loop [while/until condition]
      

      一个不错的解决方案,因为您有 4 种不同语义的可能组合:do/loop 关键字之后的 until/while。

    • 变量类型修饰符的奇怪顺序。

      int * const & i [];
      
    • 类型和变量名只是一个接一个出现,没有标记它是一个局部变量声明。 Scala 使用 valvar 确实表示声明了最终/可变变量,并且类型由冒号分隔。在大多数其他方面,Scala 使用 Java 语法。

    • 赋值运算符返回一个值;语句(有效果)和表达式(只返回一个值)之间没有区别

    编辑:这里有更多示例:https://stackoverflow.com/questions/163026/what-is-your-least-favorite-syntax-gotcha

    您肯定不会就其中的许多观点达成一致,而且并非所有观点都一定是否定的(例如分号),或者我知道一种对所有情况都更好的解决方案。即使我愿意,生成的语言也不会是完美的语言。编程语言将永远发展,新发明的语言有望向其前辈学习。那么,为什么不保留已知的语法,而不是每十年设计一个新语法呢?

    但是,当语言设计者有可能避免只是输入错误的编程错误时,为什么不改变它呢?例如,这是在 C# 的 switch 语句中完成的,这使得 break(或 goto)是强制性的。一旦最坏的缺点被消除,大多数程序员了解语法的其余部分所带来的好处远远超过从头开始重新设计语言的好处。但我仍然感到惊讶,为什么这么多程序员仍然如此热切地捍卫 C 语法,尽管这些人已经习惯了计算机科学的进步需要定期修订几乎所有内容。

    总而言之,我认为 C 语法占主导地位的唯一原因是因为几乎所有专业程序员都知道它,这些只是习惯了它。实际语法不太重要,尽管其他语言可能有优势。这也是电气工程师按原样使用电荷约定的原因。

    (也许还会有一个关于程序员拜访丹尼斯·里奇的漫画:“请不要让 switch 语句中的 break 成为可选的!”)

    【讨论】:

    • +1 请注意,易于实施有点偏离。他们还有一个严重的内存问题,并且系统(具有单独的预处理器-编译器-汇编器-链接器)旨在立即最小化内存中所需的状态,以最大化可以针对给定内存大小编译的程序大小.
    • +1 宏与 C 导致一些设计决策时的老式内存容量有关。另外,还有人喜欢自我的疯狂吗?
    • 由于有些人把左大括号放在下一行,花括号甚至可能占用更多空间。
    • 我不同意,我认为良好的语法至关重要。但除此之外,这是一个非常好的总结。
    • 请注意,我之前的评论也可以看作是 C 从一开始就投入生产使用的标志(例如,仅 4 年前的 Pascal 被设计为算法描述语言,并且不会离开学术界直到 1980 年)。无论如何,C 可能不能与 Unix 分开,既是塑造它的需求,也是它可能在 1975 年消亡的力量
    【解决方案2】:

    在我看来,实际上只有三个主要的语法元素从 C 语言传播到世界其他地方:用大括号表示的块、表示行尾的分号和一般的 "简洁”的风格。

    将块包装在单个字符中是相当合理的;首先,输入速度很快,不占用大量屏幕空间(与 BEGIN-END 关键字对不同)。其次,语法相当灵活,因此您可以在特殊情况下根据需要/想要格式化您的块(在 Python 之类的东西中您无法真正做到这一点。)最后,您的代码可能会被某些东西弄脏就像一个电子邮件客户端,并且仍然可以被人类和编译器读取(这是我在使用 python 样式的 indents-for-blocks 时遇到的唯一真正的问题)。

    为什么要使用花括号呢?我不知道在 C(或者更可能是 BCPL)中使用它们的历史先例是什么,但我可以大胆猜测一下。 “标准”美式键盘上的配对符号并不多:{} [] () 和 就是这样。如果我们想让编译器的工作更轻松,我们需要 BEGIN 和 END 的唯一符号,所以使用类似 |或 # 表示块结束。在我们的配对中,{} 确实是唯一一个不意味着什么的 - () 和 [] 都有很多数学包袱(它们或多或少直接用函数和数组翻译)并且 都意味着各种事情。我也会为块选择 {}。

    对于一种新语言,如果您不使用关键字或缩进,为什么要更改它?大批程序员习惯于用它们来表示块,为什么要使所有肌肉记忆无效?

    同样的论点也适用于使用分号。使用某些东西来表示行尾会使编译器的工作变得更加轻松。只使用一个字符可以让程序员的工作轻松很多。扫描键盘上的单个字符,从数学上讲,分号是少数几个没有多大意义的字符之一。从英语语法的角度来看,句号(或者逗号)最有意义,但它们已经被用作小数点。而且,如果您眯起眼睛,将分号作为行终止符的含义与英语中的含义相当相似。再说一次,如果你要开始一种新的语言,为什么要改变它?

    至于基本的简洁性,我认为这是您唯一可以客观地说是个好主意的。我可以输入的字符越少,以将想法传达给计算机,同时仍然足够接近英语以阅读,越好。

    (您可能会争辩说,大多数 C 类型语言也借用了大部分关键字词汇表,但实际上,大多数 C 的关键字来自 ALGOL、FORTRAN 和 BCPL 等旧语言,而且真的 - 它们都是(大部分)常识。再说一次,一旦你对编程社区进行了培训,什么是“while 循环”,为什么要更改名称?)

    我认为,今天任何不使用像 C 那样的语法的语言都是因为一些基本的范式转变(比如 Python 的缩进方法)。如果您正在制作一种基本以相同方式工作的语言,为什么要更改任何内容?您的目标受众已经可以用他们的小指敲击花括号键了,为什么要让这项特殊技能毫无价值?

    或者,把最后一句话更进一步,如果你想在你的新的、改变游戏规则的语言(Java、C# 等)上向编程社区推销你的障碍会少很多如果您的客户都已经知道语法,则跳转。

    【讨论】:

    • BCPL 没有使用大括号,它使用 $( 和 $) 对。关于它的许多卑鄙的事情之一......
    • 真的吗?成员的点、变量第一次出现时的类型/范围限定符以及函数参数的括号对您来说似乎并不常见?
    • ...嗯,是的。我尽量保持一般。 :) 但是点了。
    • @Neil Butterworth:该死,真的吗?伙计,我对 BCPL 了解得越多,我越为没有学习它而感到高兴。
    • @electrons 相信我,你什么都没错过。我学了一些 BCPL,很早以前,因为它看起来像是一种易于编写编译器的语言。如果您不使用 BCPL 编写编译器,它就是这样。它是唯一一种我永远不会在我的简历中提及的编程语言。
    【解决方案3】:

    我认为这只是风格问题,而不是优势问题。

    【讨论】:

    • 我认为这更多的是受欢迎程度的问题。 :) +1 不过。
    【解决方案4】:

    块结构语言必须以某种方式指定块。 Pascal 语言家族的相对不受欢迎似乎表明关键字不是这样做的好方法。另一方面,Python 的流行可能意味着未来更多的语言将单独使用缩进来表示结构——但我希望不会。

    【讨论】:

    • 缩进或大括号,至少它不是 Lisp 样式的格式。 )()()()())((()))()
    • 将单词作为块分隔符的好处是您可以确定您当前关闭了哪个块或错过了它!将 End If End While End 函数与 } } } 进行比较
    • -1 一种语言的流行度通常不是基于表面的语法。凭空得出的危险结论。
    • 因此我使用了“似乎”和“可能”这两个词。
    • 似是而非的措辞不再有效。例如:您使用此类词似乎表明您可能殴打您的母亲。
    【解决方案5】:

    确实,当 c 简洁易懂时,为什么要发明一种全新的语法。大多数编程都熟悉 c 并且语言本身是用 c 实现的,这也有帮助。这是为什么要尝试改进已经非常有效的东西的一个例子。

    【讨论】:

    • 这与“C 流行”相同。它没有解释为什么语法 got 流行。
    【解决方案6】:

    人们已经习惯了。当它被发明时,每一种语言都丑陋得要命。那时,C 因吸得少而广受欢迎。 (也许是因为比 LISP 更脚踏实地)。

    今天,其他语言重用该语法,因为它为程序员所熟悉。

    我认为没有比这更多的了。我更喜欢大括号而不是开始/结束(尽管大括号在许多非英语键盘上很痛苦),但仍然有很多 C 语法的怪癖可以做得更好。 C++ 发现返回类型可能更适合参数之后(C++0x 允许这种语法,因为它与 decltype 等其他新特性配合得更好)。

    而且大多数函数式语言已经意识到参数周围的括号通常是不必要的。就此而言,通常也不需要显式键入。但是大多数语言都从 C 继承了这一点,因为“这就是语法”。先输入,再输入变量/函数名。

    让我们甚至不要进入可憎的函数指针。当然,我们可以为 它们的 类型找到更优雅的语法。或者尝试 typedef'ing 数组类型。

    然后是运营商的古怪选择。为什么不直接使用“and”而不是&&?

    C 的语法不好。它完成了这项工作,我们已经习惯了它,它可能会继续存在。但这不是“好”。

    【讨论】:

      【解决方案7】:

      C 风格的语法非常紧凑。根据情况,这是一个缺点或优点。无论如何,这对高级 C 编码人员来说是一个生产力提升。

      许多新语言正式宣称继承了 C,例如C++、C#、Objective-C。

      而且,我猜很多语言的创造者都有很大的 C 背景。不管有意与否,他们可能会用新语言复制他们最了解和他们认为最有效的东西。

      【讨论】:

        【解决方案8】:

        是否有任何客观原因可以解释这种语法的广泛传播和成功?

        不是很客观,但 C 具有三个主要的历史优势:

        • 当时它比其他语言更简洁(使用 {} 而不是 Algol 的开始/结束)
        • 它没有明显的缺点(例如 Fortran 有歧义,不支持一行中的多个语句)
        • 在它流行之后,几乎所有其他语言设计者都知道 C,并且可能使用 C 来构建他们语言的工具集

        与其他语言的语法相比有什么优势吗?

        嗯,有明确的块和语句分隔符允许多语句表达式;例如,您不能在 Python 中执行多语句 lambda 表达式(不是说您在 C 中有 lambda,尽管您在最新的 C++ 中执行)。只需要为块输入一个字符是一个小优势,但不是一个很大的优势(设置一个编辑器来匹配“开始”到“结束”可能比匹配 C 更容易(“{”或“?? "),如果打字速度是您编程中的限制因素,那么您可能没有自动完成您应该做的任务)。

        【讨论】:

        • 重新阅读了一些 Brian Kernighan 的文章,似乎添加大括号主要是为了消除悬空 else,同时提供基于标记的语句块视图。
        • 设置编辑器以匹配“开始”到“结束”可能比匹配 C 的 (“{” OR “??" -- 尽管禁用三元组更容易。
        • 从什么时候开始,简洁是一种绝对优势?我想知道我们为什么要使用汇编程序,而机器代码肯定更简洁。
        • @MarcovandeVoort C 和 Algol 在几乎相同的抽象级别上运行,因此它可能是一个次要优势。我并没有说简洁凌驾于抽象层面。
        • 我的意思是,在相同的抽象级别下,简洁性也会对可读性产生不利影响。
        【解决方案9】:

        至于为什么大括号流行起来......两个原因:

        1. 风洞效应。对于任何给定的问题,只有这么多好的解决方案,对问题的分析越多,这些问题的解决方案就可能变得越相似。因此,2009 年雪佛兰更接近 2008 年福特,而不是 57' 雪佛兰和 '57 福特……新雪佛兰和新福特设计在同一个风洞中。花括号和分号具有简单的工程意义,使得 C 比“块”风格的可比语言更容易解析(对于计算机和人类)......因此 C# 与 Java 非常相似,以至于我有时会暂时忘记哪种语言我正在使用。

        2. (如前所述)对于程序员来说,学习一种“看起来和感觉上都像”以前的模型的新语言要容易得多。不要重新发明轮子,它不会在你身上翻滚;-)

        干杯。基思。

        PS:我预测,在 50 年内,我们将使用“自然语言”编译器......并深情地回忆起花括号语言的美好时光,当时男人在男人面前,羊在害怕的地方。

        【讨论】:

          【解决方案10】:

          Afaik C 的流行与 Unix 的流行直接相关,而不是它的语法。这一点有多个方面;它的低级语言 (*) 和适用于内核开发的瘦 强制 库、编译器的可用性、跨系统兼容性的相对早期尝试。

          如果我不得不说出第二个原因,那就是相对松散的构建模型(编译单元只在链接器处相遇,只有链接器第一次看到(大部分消化的程序)完成),这对于低记忆系统。

          人们常说代码密度,但那是后来的修正主义。至于后来采用这种语法的语言,更多的是希望它能让升级路径变得更容易,而不是语法的优越性。除了块语法和名称之外,这在与 C 相距甚远的 C# 中清晰可见。

          (*) 我更多地暗示了很多编译器助手的缺失。如果将 libgcc 的内容缩减到 K&R 级别,则或多或少会影响它的内容。

          【讨论】:

            猜你喜欢
            • 2016-07-10
            • 2013-10-26
            • 2014-01-19
            • 1970-01-01
            • 2023-03-09
            • 2012-02-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多