什么是计算机编程语言?

9
冒昧地问一句,我想深入了解编程语言的概念。为了自己和他人的启示,我写下这个问题。
什么是计算机编程语言的有用定义,它的基本和必要组成部分是什么?有哪些关键特征区分语言(函数式、命令式、声明式、面向对象、脚本等)?
思考这个问题的一个方法是:想象你正在看现代台式电脑或笔记本电脑的硬件。假设C语言或其变体不存在。你会如何向他人描述所有需要的东西,使计算机在我们今天对个人计算机的期望方面具有表现力和功能性?
与此相关的是,计算机语言中存在什么,使得其他语言也能存在?例如,以Javascript、Perl或PHP为例的脚本语言。我认为这些语言的定义的一部分是,最可能在某个层次上使用C或C++实现的解释器。是否可以用Javascript编写Javascript的解释器?这是一个完整语言所需的要求吗?同样适用于Perl、PHP等。
我将满意于可以进一步查找或研究的概念列表。

可能是什么是编程语言?的重复问题。 - nawfal
11个回答

27

和任何语言一样,编程语言只是表达和传达想法的沟通工具。在这种情况下,我们将软件如何运作的想法转化为计算机(以及大多数人可以理解该语言的其他人)可以阅读和理解的结构化和有条理的形式。

什么是计算机编程语言的有用定义,以及它的基本和必要组成部分是什么?

我认为编程语言的定义特征如下:使用该语言编写的内容旨在最终被转换为可执行内容。因此,虚拟代码虽然可能具有编程语言的结构和严谨性,但实际上并不是编程语言。同样,UML可以像编程语言一样以抽象方式表达许多强大的想法,但它不能满足人们通常不会编写UML来执行的需求。

您如何向他人描述使计算机表达和功能符合我们今天对个人计算机的期望所需的所有东西?

即使“编程语言”不是我与人交流时使用的共享词汇之一,我认为其他人也会明显感觉到我们需要一种与计算机进行通信的方式。正如没有人期望汽车在没有方向盘和踏板的外部指令的情况下(目前还没有!)自行驾驶一样,没有人能指望硬件在没有被告知该做什么的情况下运行。正如上面所提到的,编程语言是我们可以通过它实现这种通信的渠道。

与此相似,让其他语言存在的计算机语言特点是什么?

所有有用的编程语言都具有称为图灵完备性的属性。如果图灵完备集合中的某个语言可以执行某项操作,则任何图灵完备语言也可以执行该操作; 它们被称为计算等效

但是,仅仅因为它们同样“强大”并不意味着它们对人类来说使用起来同样舒适。这就是为什么许多人愿意牺牲在汇编代码中编写时获得的无与伦比的微观管理,以换取更高级别语言(例如Ruby、Python或C#)带来的表达力和功能。

是否可能使用Javascript编写Javascript解释器?这对于一个完整的语言来说是否是必要的?对于Perl、PHP等语言也是一样吗?

由于已经有一个用C编写的Javascript解释器,因此可以得出结论,使用Javascript编写Javascript解释器是可能的,因为两者都是图灵完备的。但是请注意,图灵完备性并不意味着在一种语言中完成某项任务比另一种语言更容易 - 只是说明这项任务从理论上是可行的。你使用Javascript编写的内部Javascript解释器可能效率极低,消耗大量内存,需要巨大的处理能力,并且代码非常丑陋。但是图灵完备性保证了它是可以完成的!


2
非常好的回答!我想补充一点(关于最后一点),不仅可以这样做,而且通常会使用另一种语言(C很常见)来创建语言,然后创建可以编译语言本身的编译器或解释器。FORTH、LISP、Scheme和C++立即浮现在脑海中 - 所有这些都是这种方式(尽管有些方式不同于其他方式)。 - Mei
我可以用JavaScript制作一个JavaScript解释器:eval(code); LOLOLOLOLOLOL - user216441
@M28:我假设你是在开玩笑,但是实际上eval()并不是真正意义上的JavaScript解释器。例如,x = 5;是有效的JavaScript代码,但是你不能将其传递给eval();你必须将其放在引号中。但是,字符串"x = 5;"x = 5的意义不同。因此,eval()略有不足。 - John Feminella
很好的解释,但第一段中的某些内容让我思考:“[...]计算机(以及其他人类)是否可以交换使用?”此外,我认为“计算机”这个词不太准确,你需要一个编译器将“计算机语言”翻译成计算机可以理解的东西,或者一个解释器来“理解”计算机语言(通过将语句翻译成子程序调用)。我知道这是一个非常古老的答案,但问题仍然年轻 :-) - Wolf

6

虽然这并没有直接回答你的问题,但我想起了Paul Graham关于编程语言演变的文章《程序员复仇》。这是一个很有趣的研究起点。


谢谢Greg。看起来是一篇有趣的文章。我一定会读它的。 - Gordon Potter

4

这里有一些稍微冗长的抱怨。

计算机语言实际上与人类语言并没有太大不同。两者都用通用理解的术语来表达想法和概念。虽然不同的人类语言有句法差异,但是你可以用每种语言表达相同的事情(这是否意味着人类语言是图灵完备的? :))。有些语言比其他语言更适合表达某些内容。

例如,尽管技术上不完全正确,因纽特语似乎非常适合描述各种雪。在我看来,日语非常适合表达自己的感受和心境,因为它在这方面拥有大量简洁的词汇。德语由于具有明确的语法而非常精确。

不同的编程语言也有不同的专长,但它们主要区别在于表达所需的详细程度。人类语言和编程语言之间的重大区别主要在于编程语言缺乏许多词汇,并且具有极少的“语法”规则。通过库,您可以扩展语言的词汇量。

例如:

给我做咖啡。

对于人类来说非常容易理解,但这仅因为我们知道每个词的含义。

coffee :一种由热带灌木的烘焙和研磨豆状种子制成的饮料
drink :可被吞咽的液体
swallow :使或允许通过喉咙
…等等

我们都能记住这些定义,但我们必须在某个时候学会它们。

同样地,计算机也可以“学习”“理解”单词。

Coffee::make()->giveTo($me);

这在计算机语言中是一种完全有效的表达方式。如果计算机“知道”Coffeemake()giveTo()的含义,并且$me已经定义,那么它表达了与英语句子相同的意思,只是使用了不同、更严谨的语法。
在不同的环境中,为了达到相同的结果,你需要说出略微不同的话。例如,在日本,你可能会说:
コーヒーを作ってもらっても良いですか? Kōhī o tsukuttemoratte mo ii desu ka?
大致翻译为:
if ($Person->isAgreeable('Coffee::make()')) {
    return $Person->return(Coffee::make());
}

同样的思路,同样的结果,但是$me是隐含的,如果你不先检查isAgreeable,你可能会得到运行时错误。在计算机术语中,这有点类似于Ruby隐含返回最后一个表达式的结果("语法特征"),并首先检查可用内存(环境必需品)。
如果你和一个词汇量很小的人交谈,你可能需要更详细地解释:

去厨房。
拿一个锅。
把锅里装满水。
...

就像汇编语言一样。:o)
无论如何,重点是,编程语言实际上就像人类语言一样。它们的语法不同,并专门针对问题领域(逻辑/数学)和“听者”(计算机),但它们只是传达想法和概念的方式。
编辑:
关于“为听者优化”的另一个观点是,编程语言尝试消除歧义。例如,“给我冲杯咖啡”可能从技术上讲被理解为“把我变成咖啡”。人类可以直观地判断意图,计算机则不能。因此,在编程语言中,通常每件事都只有一种意义。如果不是这样,你可能会遇到问题,JavaScript中的“+”操作符就是一个常见的例子。
1 + 1     -> 2
'1' + '1' -> '11'

很好的回答。我喜欢你对汇编语言的比喻和更多细节的需求。 - Gordon Potter

4

这并不是一个定义,但我认为编程语言的发展主要有两个方向:

  • 从机器可以做到的事情开始逐步向更具表达性和与机器解耦的方向发展(汇编语言、Fortran、C、C++、Java等)。

  • 从一些数学或理论计算机科学概念开始向实际可实现的机器上转化(Lisp、Prolog、ML、Haskell等)。

当然,在现实中情况并不如此简单,这两种方向会通过借鉴最好的思想互相影响。


3

很遗憾,你的第二个链接已经失效了。在看完第一个链接后,我很好奇它是什么内容。顺便说一句:一开始给链接添加页面标题似乎是多余的,但有时候它变得至关重要... - Wolf

2
作为一位朋友教给我的计算机语言,一门语言就是一个世界。这是与机器交流的世界。它是实现想法、算法和功能的世界,正如Alonzo和Alan所描述的那样。它是前面提到的科学家们建立的数学结构的技术等价物。它是一种带有表达式和限制的语言。然而,正如路德维希·维特根斯坦所说:“我语言的限制意味着我的世界的限制”,总会有局限性,这就是人们选择更适合自己需求的语言的原因。
这只是一个通用的答案......实际上是一些思考,而不是一个答案。

我喜欢维特根斯坦的引用。维特根斯坦还说过:“世界是事实的总体,而不是事物的总体。”也许我们可以将这类比于二进制信息的工作方式。因此,一个程序是由编译后的编程语言所表达的“二进制”事实的总体。 - Gordon Potter

2
有趣。
我认为编程语言的定义特征是基于输入做出决策的能力。实际上,就是if和goto。其他所有东西都是大量的语法糖。这就是产生Brainfuck的想法,尝试使用它其实非常有趣。
有些地方界限模糊;例如,我怀疑人们是否认为XSLT真正是一种编程语言,但它是图灵完备的。我甚至用它解决了一个Project Euler问题。(非常,非常慢)
我想到了三个主要属性:
1.如何运行?它是编译成裸机(C)、编译成几乎裸机带有一些运行时查找(C++)、在JIT虚拟机上运行(Java、.NET)、字节码解释(Perl)还是纯解释(嗯..)?这并没有对语言本身进行评论,但说明了代码的可移植性、我可能期望的速度(因此哪些广泛的任务会很好地工作),以及有时语言的灵活性。
2.它支持什么范式?过程化的?函数式的?标准库是用类还是函数构建的?有反射吗?理想情况下,支持我想做的任何事情?
3.如何表示我的数据?有数组吗?它们是固定大小的还是不固定大小的?使用字符串有多容易?有结构体或哈希内置吗?类型系统是什么样的?有对象吗?它们是基于类还是原型的?一切都是对象,还是有原语吗?我可以从内置对象继承吗?
我意识到最后一个问题是一个非常庞大的问题集,但在我看来,这些都是相关的。
我想象完全从头开始重建编程语言的景象会和第一次一样:迭代。从汇编语言开始,即处理器理解的直接命令列表,并用一些更容易使用的东西包装它。重复,直到你满意为止。
是的,你可以用Javascript写一个Javascript解释器,或者用Python写一个Python解释器(参见:PyPy),或者用Javascript写一个Python解释器。这样的语言被称为自托管。看看Perl 6;这一直是它的主要实现的目标。
最终,一切都必须转换为机器代码,而不一定是C。你可以写D、Fortran、Haskell或Lisp。C只是一个旧标准。如果你为语言Foo编写了一个编译器,可以通过任何方式最终输出机器代码,那么你可以在Foo中重新编写该编译器并跳过中间人。当然,如果你的语言是纯解释的,这可能会导致堆栈溢出...

你要找的术语是图灵完备。简单来说,这样的语言可以编写任何程序,而不是TC的语言只能执行有限的任务集。例如,SQL不是图灵完备的,而Basic是。 - Martin Beckett
糟糕,那是一个糟糕的打字错误;我的错误。 - Eevee

2

人类表达式可以:

  • 描述数学函数
  • 让计算机开关打开和关闭

2
这个问题很宽泛。我最喜欢的定义是编程语言是一种表达计算的方式。
精确地说,在我们可以推理的高级方式中,通过计算我指的是图灵和教堂所指的:图灵机和λ演算具有相等的表达能力(这是一个定理),而教堂-图灵假设(这是一个猜想)大致意味着没有更强大的计算概念存在。换句话说,任何编程语言可以表达的计算类型最多只能使用图灵机或λ演算程序来表达,并且某些语言只能表达其中的一个子集。
计算的这个定义也包括您友好的硬件,使用图灵机进行模拟非常容易,使用λ演算进行模拟甚至更容易。
“精确地”表达计算意味着计算机不能逃避其义务:如果我们有一个特定的计算在脑海中,我们可以使用编程语言来“强制”计算机执行该计算。(带有“实现定义”或“未定义”结构的语言会使这项任务更加困难。使用这些语言的程序员通常愿意接受 - 或者可能不知不觉地接受 - 与他们所想的计算仅密切相关的一些计算。)
以“高级方式”表达计算是编程语言的全部内容。存在如此多不同的编程语言的一个重要原因是有许多不同的高级问题解决方法。通常,如果您有一个重要的新问题类需要解决,那么最好创建一个新的编程语言。例如,拉里·沃尔(Larry Wall)的写作表明,解决一类名为“系统管理”的问题是他创建Perl的动机之一。
(创建新语言的另一个原因是这样做非常有趣,任何人都可以学会它。)
最后,许多程序员希望语言使得对程序进行推理更容易。例如,今天我的一个学生实现了一个新算法,使他的程序运行速度提高了六倍。他必须非常仔细地推理C数组的内容,以确保新算法将完成与旧算法相同的工作。幸运的是,C具有用于推理程序的良好工具,例如:
- 更改a [i]不能影响a [i-1]的值。
我的学生还应用了在C中无效的推理原则:
- 无符号整数序列的总和将至少与序列中的任何整数一样大。

在C语言中这并不正确,因为求和可能会溢出。一些程序员喜欢像Standard ML这样的语言,因为在SML中,这种推理原则总是有效的。在被广泛使用的语言中,可能Haskell有最强的推理原则,Richard Bird已经将程序的等式推理发展到了高超的艺术水平。


我不打算解决你开头问题中所有的细枝末节。但我希望你会从回答中获得更深刻的理解,因为你询问的是有关编程语言基本问题的。


感谢您对图灵完备性的解释。我曾听说过这个概念,但并没有完全理解。您的回答提供了很好的澄清。 - Gordon Potter

2

很多“IT”人士经常忘记计算机编程语言分为两种:

  1. 软件编程语言:C、Java、Perl、COBAL等。

  2. 硬件编程语言:VHDL、Verilog、System Verilog等。


(注意:保留HTML标签,不做解释)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接