语法在编程语言中真的重要吗?[关闭]


41

我的一位教授说“语法是一种编程语言的用户界面”,像Ruby这样的语言具有很好的可读性,并且还在不断增长,但是我们看到很多程序员都能用C \ C ++高效工作,因此程序员确实对语法很重要应该可以接受吗?

我很想知道您对此的看法。

免责声明:我不是要吵架。我认为这是一个很好的讨论话题。

更新:原来这是一个很好的话题。我很高兴你们都参与其中。


16
嗯,这似乎是假设C / C ++语法不好?当然,C ++模板的某些元素很难看,但是就语言而言(历史上而言),C / C ++仍然非常非常易读。
Macneil 2010年

2
好吧,我知道许多程序员会不同意这一点,尽管据我所知,它主要是来自ruby社区,而不是
Lisp

9
这是理论课程吗?请记住:教授通常是最糟糕的程序员之一。他们不知道野外的感觉是什么。
作业

2
易读性是情人眼中的:)。
MAK 2010年

8
良好的语法不能使悲惨的语言变得更好。但是糟糕的语法会使好的语言变得更糟;)
Dario

Answers:


65

是的,它确实。如果您有疑问,请使用APLJBrainfuck,甚至是简单的Lisp或Forth,然后尝试了解其上所有不完全琐碎的程序。然后与Python比较。

然后将相同的Python(或Ruby,甚至C#)与Cobol或VB6之类的东西进行比较。

我并不是要说多毛的语​​法是不好的,而类似自然语言的语法在所有情况下都是好的。但是句法过时的语法确实有很大的不同。总而言之,您可以使用最精美的编程语言编写的所有内容,也可以作为图灵机程序编写的所有内容-但是您通常不愿意,是吗?


26
Lisp绝对是可以理解的。
cbrandolino

65
+1,表示将Lisp包含在不可读的语言列表中。
asmeurer 2010年

65
-1,表示将Lisp包含在不可读的语言列表中。
保罗·内森

27
一般而言,编程对于初学者来说是不可读的。音乐符号和建筑平面图也是如此。对于知道如何阅读的人来说,(= XY)与X == Y一样可读。
保罗·内森

6
我喜欢APL,除非有意编写代码以使代码模糊(非常容易做到),否则它很容易阅读。语法的强大功能在于您可以用2或3行APL代码来编程算法,而这需要数十行或数百行C,Fortran或COBOL。像APL这样的语言的简洁性和威力对本次讨论很重要,因为试图通读另一种语言的数百条代码行可能与破译APL晦涩难懂的内容一样令人沮丧。
oosterwal

11

实际上,我认为这很重要。上面已经讨论了可读性。另一个问题可能是需要表达多少个击键来表达一个想法/算法?另一个问题是,简单的错字很难被人的眼睛捕捉到,它们会造成多大的恶作剧。

我还发现在某些情况下通过另一个计算机程序进行分析和/或生成代码片段非常有用。解析语言和/或生成正确代码的难度直接影响创建/维护此类工具所需的工作量。


关于错别字的出色观察,易于区分。

7
但是在理论上,理论与实践之间没有区别。
工作

10

我相信您的教授指的是语法糖

语法糖是计算机科学术语,指的是一种编程语言中的语法,旨在使事物更易于阅读或表达,同时存在表达它们的替代方法

因此,您的教授所暗示的是,用一种编程语言编写的任何代码/语法都可以用相同或什至相同的语言来表达。

罗伯特·马丁(Robert Martin)从结构化编程定理的基础上,在RailsConf 2010上的主题演讲中抽象了程序员从根本上对编程语言所做的事情:罗伯特·马丁(youTube视频,经过14分钟后,尽管我推荐整件事):

  • 顺序(分配)
  • 选择(如果语句)
  • 迭代(循环执行)

从一种编程语言到另一种编程语言,程序员所要做的只是使用不同的语法或用户界面(UI)。如果他/她正在抽象地谈论编程语言,这就是我想你的教授正在讲的内容。

因此,在本质上语法并不重要。但是,如果您想具体一点,那么显然某些语言和语法比其他语言更适合于某些任务,因此您可以说语法很重要。


您是否将C称为汇编程序的语法糖?
Goran Jovic 2010年

1
我会。但是我声称语法很重要。;)
Lennart Regebro 2010年

2
“……罗伯特·马丁(Robert Martin)抽象了程序员的基本工作……”罗伯特·马丁?罗伯特·马丁 您可能实际上可能要考虑这篇文章:C.Böhm,G。Jacopini,“仅具有两个编排规则的流程图,图灵机和语言”,通讯。ACM,9(5):366-371,1966。通常被认为是“结构化程序定理”的来源。en.wikipedia.org/wiki/Structured_program_theorem
leed25d 2010年

@ lee25d我并不是要把Bob叔叔归功于抽象的发起者,而是我最近听到(并链接到)它的来源。但是感谢您提供的链接,我将更新我的回答以反映您的链接。
2010年

上面链接的Wikipedia文章不太了解“结构化编程定理”的历史。这个想法早于Bohm&Jacopini。Bohm&Jacopini的贡献表明,它是一个定理,而不仅仅是一个猜想,也就是说,他们提供了严格的形式证明。
约翰·斯特罗姆

7

是的,没有。

语法有几个不同方面。

  • 可读性
  • 表现力
  • 可解析性

可读性已经被提及。

表达能力是一个有趣的案例。我将以函数传递为例,因为它是语义/句法痛苦的转折点。

让我们以C ++为例。我可以按照这种方式创建一阶函数:

class funcClass
{
  int operator()(int);
}
funcClass fun;

void run_func(funcClass fun)
{
   fun();
}

这个特定的习语通常在Stepanov的《编程元素》中使用

在另一方面,我可以像模仿它的Common Lisp

(defun myfunc() )

(defun run_func(fun)
  (fun))

或者,在Perl中-

   sub myfunc
   {
   }

   sub run_func
   {
      my $func = shift;
      $func->();          #syntax may be a little off.
   }

或者,在Python中-

def myfunc():
    pass

def run_func(f):
    f()

尽管C ++示例带有某种类型的元数据,但它们基本上都具有相同的语义内容。哪种语言最能表达通过高阶函数的想法?Common Lisp几乎没有语法上的变化。C ++要求仅创建一个类以“承载”函数。Perl关于进行某种程度的区分非常简单。Python也是如此。

哪种方法最适合问题领域?哪种方法最能以“阻抗不匹配”最少的方式表达您的想法?

在我看来,可解析性非常重要。特别是,我指的是IDE能够解析和砍切语言而不会出错的功能。重新格式化很有用。令牌分隔的语言往往能很好地解析-ruby / c / pascal等。

请考虑一下-已经用每种严肃的语言创建了各种主要系统来解决现实世界中的问题。尽管语法是表达某些内容的障碍,但它是可解决的障碍。图灵等价物。


5

语法绝对很重要,尽管在不直观的情况下您会经常注意到它,并且会引发错误。例如,臭名昭著的“世界上的最后一个错误”笑话:

if (AlertCode = RED)
   {LaunchNukes();}

2
+1:有趣的是,我从未见过(或承认)这个臭名昭著的“世界上最后一个错误”笑话。但是我可以看到,根据语言的语法(甚至实际上甚至是语义),伪代码的结果可能是任何东西。同样从语义角度出发,这确实可以归结为文化交流错误的经典案例。
斯蒂芬·斯文森

这就是为什么您应该使用Yoda条件,即if(RED = AlertCode)永远不要编译,因为RED是恒定的(或者应该是!)
Malfist 2010年

4
@Malfist:因此,我们看到语法错误会导致语法更糟,无法弥补。Yoda条件句很难看懂,因为它们不是人们对相关概念的看法。我的意思更像是“这是(许多原因之一)为什么您应该尽可能避免使用C族”。
梅森惠勒

1
幸运的是,该代码有两个错误。当然,它将始终输入条件,但在那里,它只是获得对LaunchNukes过程的引用,而从不调用它。避免危机!
优厚的

3
取决于是什么RED。如果为0,则LaunchNukes()永远不会调用。
2011年

5

语法确实很重要,我可以举两个支持的例子:Dylan,它是具有更常规语法的Lisp,Liskell,是具有类似Lisp语法的Haskell。在每种情况下,都提出了一种语言的变体,该变体具有完全相同的语义,但语法却截然不同。

在Dylan的情况下,人们认为放弃s表达式而转向更传统的东西将有助于吸引更多的程序员。事实证明,语法并不是阻止程序员使用Lisp的唯一方法。

在Liskell的情况下,人们认为使用s表达式将允许更轻松地使用宏。事实证明,在Haskell中确实不需要宏,因此该实验也不起作用。

事情是这样的:如果语法对任何人都不重要,那么就不会尝试任何实验。


1
迪伦太少了,与其他语言相比太晚了。它所拥有的优势无法弥补这一点。我们不能再假设它是语法失败,而不是命名失败。
Macneil 2010年

@Macneil:你说得太少了,太晚了。放弃Lisp语法只是棺材里的最后钉子。我不认为这是Dylan失败的主要原因,但是我不确定如何重新措辞以最好地反映这一点。
拉里·科尔曼

有趣的是,我不知道他们在较早的版本中具有Lisp语法……那是它的名字叫Ralph吗?牛顿留言板原本以Dylan为核心。15年后,我们有了以Objective-C为核心的iOS,这是两者中的次要语言,恕我直言。
Macneil 2010年

我不记得有关Dylan何时失去S表达式的确切细节。我一直潜伏在comp.lang.lisp上很长时间了,还记得这个话题出现在他们对括号进行的一次定期大战中。
拉里·科尔曼

Dylan早于Java,但我不认为那时有很多C ++。
Tom Hawtin-大头钉

3

答案可能是将“问题”分为计算机因素人为因素。语法中有很多人为因素:

  • 可读性
  • 简洁
  • 可维护性
  • 教育学
  • 错误预防
  • 目的是否适当-是REPL语言,脚本语言还是大型系统语言?

就计算机而言,语法的唯一问题是是否需要解决歧义性,以及在编译/解释时对代码进行标记/解析需要花费多少时间-仅在这种情况下后者的解析开销很重要。

这也许就是为什么您总是对这个问题回答“是与否”的原因-因为有两个方面。


1

没有语法,我们将没有一个通用的“模板”,可以在人的层面上与他们交流代码块的意图。语法提供了一个通用框架,通过该框架可以对编译器进行标准化。方法可以共享;维护可以简化。


为什么我的回答被否决?
IAbstract

1

我认为真正重要的是API访问以及在需要时提供低级功能(例如内存控制和锁定)。大多数其他语言都包含这些功能。问题是,当您需要其他功能时,通常必须使用C之类的语言来实现它。而且,将C与您使用的语言连接起来很麻烦。

对于 Web开发(和数学)以外的所有内容,我发现C / C ++仍然是操作系统和应用程序的语言。大多数时候,真正的多线程,预执行,跨平台应用程序开发都支持此功能。C的语法还可以。只是非常简单且相对冗长。惊人的语法并不重要。强大的功能和API的可用性确实我们都需要与其他人的代码对接(大多数时间是用C或其派生语言编写的)。


我对C没有什么不满,但是ML / Haskell人群可能会对线程有话要说。
宫阪丽

为“ API访问权限” +1:我认为这甚至比语言功能还重要。
乔治

1

语法绝对重要。如果语言语法足够灵活以允许您为您的应用程序创建方便且可读的特定于域的语言,那将对我们非常有用。如果您对此表示怀疑,请想象一下像18世纪之前那样在平淡的拉丁语中进行代数运算,或者想象没有现在熟悉的莱布尼兹(Leibniz)表示法进行微积分。当然,微积分的文本对于新手来说是不可读的,但是通过实践,我们可以使用微积分和Leibniz表示法快速解决一类问题,这些问题需要使用经典方法进行数学计算。编程只是数学的又一小部分。靠近问题域的方便注释可以在生产率上产生巨大差异。


DSL不仅与语法糖有关。语义是更有价值的部分。可以设计不会在现有语法中添加任何内容的eDSL。
SK-logic

@SK:可以,但是语义在程序员的完全控制之下。语法受基本语言约束。我们可以在Groovy和其他语言中构建便捷的DSL,而在Java中则没有那么多。
凯文·克莱恩

1

这是一个计算6的能力的程序:

S(K(S(S(SI(KK))(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)
(S(KS)(S(K(SI))K))))(KK)KK))))))(S(K(S(S(K(SI))(SII)(S(K(SI))(SII))
(S(K(S(S(KS)(S(KK)(S(SI(KK))(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)KK)))))))
(S(K(S(S(KS)(S(K(SI(KK)))(SI(K(KI)))))))(S(K(S(K(S(S(K(SI))(SII)(S(K(SI))
(SII))(S(K(S(S(KS)(SI(KK)))))(S(S(KS)(S(K(S(KS)))(S(K(S(KK)))(S(S(KS)K)
(K(SI(K(KI))))))))(K(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)))))))))))
(S(S(KS)K)(K(SI(K(KI)))))))))))(S(S(KS)K)(K(SI(K(KI))))))(S(S(KS)(S(KK)(S(KS)
(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)
(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)
(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)
(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)KK)))))))

语法是最小的:

expression: expression term | term
term: ‘(‘ expression ‘)‘ | combinator
combinator: 'S' | 'K' | 'I' 

似乎普遍认为语法是使语言变得困难的原因。正如通常所持的信念那样,事实恰恰相反。

请注意,LISP语法仅可读(如果有的话),因为它的语法比上述语法多得多。因此,如果LISP粉丝告诉您“语法无关紧要”,请要求他们这样做,然后尝试SKI演算。他们将不得不承认一点点语法毕竟还算不错。


我不明白这次的否决票。这是一个非常有见地的答案。+1
时髦的

0

我认为这并不超出个人喜好。所有事物(性能,能力等)都是相等的,那么我就能明白为什么人们会更加重视一种语言语法,却选择通过诸如c / c ++之类的语言或其他更适合该工作的语言来超越性能,这仅仅是因为语法似乎是个坏主意。


6
“上市时间”,“受益成本”等如何?
工作

0

是的,语法很重要,尽管实际上只是为了提高可读性。相比:

for i in range(10):
   print(i)

(是的,是Python)

FOR(i<-RNG-<10){PRN<-i}

(是的,这是我刚刚编写的一种语言)两者将以相同的方式做完全相同的事情,但是语法不同,并且Python更易于阅读。是的,语法绝对重要。甚至“语法糖”也很重要。

 @property
 def year(self):
     return self._date.year

比起阅读更容易

 def year(self):
     return self._date.year
 year = property(year)

0

是的,当然。

如果您想激起大火,请问乡亲们,他们在哪里用类似于C的语言打开开头。我的意思是

void foo() {
  // blah
}

VS

void foo()
{
  // blah
}

甚至VS

void foo() 
{ // blah
}

这只是同一语言!另外,询问他们有关空格的信息,以及它们的放置位置(函数名称和bracet,运算符等)。

保证有1000个答案!


我不想引起
骚动

0

语法确实很重要。但是,在当今这个时代,我会说这几乎完全重要,因为它具有可读性,而实际上并不是所需的击键次数。为什么?

  • 除非您真的写了这么简单的东西,否则如果您按的键数是编写程序的限制因素,那么您要么真的非常讨厌打字,要么想得太多,太快了。
  • 如今,所有不错的IDE都有大量的快捷键,这意味着您无需真正键入大部分时间使用的所有字符。

就是说,如果它冗长,那么它可能会影响可读性。我希望看到类似以下内容:

foreach(stringList中的字符串)

至:

对于stringlist变量引用的列表中的每个String

...任何一天!


0

语法对那些正在学习它的人很重要,进入的障碍越低,该语言最初可能会越流行。但是,如果很难或不可能用这种语言来丰富而简洁地表达自己的语言,它将开始流行。

非常简洁和不透明(Perl)与过于冗长和冗长(AppleScript)一样糟糕。

需要保持平衡,降低进入门槛,提高生产率和易于维护。


-2

还要考虑的另一件事是,具有更好语法的编程语言更易于解析,从而使编译器更易于编写,更快且更不容易出现错误。


3
嗯... parse.yRuby中的10000 SLOC 意见不一。还有就是为什么有原因的每一个的7电流或淳生产就绪的Ruby实现的采用了相同的解析器,并且每一个是曾经尝试开发自己的Ruby实现自己的解析器失败。
约尔格W¯¯米塔格

然后是臭名昭著的ADA语言。除了语言规范外,还有100个程序必须正确运行才能验证编译器。关于语法有一些非常微妙的东西。长话短说,每个早期的ADA编译器构建都会使其中一些程序不合格。修复错误并不是一件简单的事情,但是他们需要从头开始。即使它得到了政府的大力支持(所有DOD合同都规定了ADA),但它却不幸丧命。
Omega Centauri 2010年

-2

简单地说:这样的语法并不重要。您可以通过它表达的语义很重要。


5
作为练习,请用C写一个复杂的解析器,然后用Haskell写一个设备驱动程序。语法对您有帮助吗?然后以相反的方式进行操作,严格保留两个程序的语义。</ irony>
9000 2010年

1
@ 9000:我在Haskell中看到了几个设备驱动程序。我看不出他们有什么特别的错误。关心详细吗?
约尔格W¯¯米塔格

2
@ 9000,鉴于在C中正确获取设备驱动程序有多么困难,所以我不确定您是否选择了一个很好的例子。

1
@ 9000:正是我的意思。句法结构的具体性质无关紧要,这就是您要表达的内容。具有Haskell 确切语法但使用不同评估策略的编程语言将使许多Haskell糟糕地执行,甚至陷入无限循环。当涉及句法构造(或更广泛的:语言功能)时,重要的不是它们的具体语法,而是它们的语义,即您可以用它们表达什么。
back2dos

@ 9000,用类似C的语法在Haskell中编写解析器(或使用类似Haskell的C使用C的驱动程序)将不是问题。
SK-logic
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.