谢谢邀请。
当谈到并发和并行时,不同的应用领域对这两个词的定义很不一样。服务端编程中,很少说「并行」的概念,而「并发」则有,指的是服务器处理同时到来的请求的能力。客户端编程中,并发和并行同时存在。此时「并发」主要指的是单 CPU 处理下的分时多进程/多线程;而「并行」则指的是多 CPU(或 GPU) 情况下的「真实」多进程/多线程处理。另外,在大数据领域,将输入数据分片切割分配到不同机器上同时处理,也被说成「并行」,可算是服务器场景中的一种。
从上面这个定义看,如今我们没有对所谓「并发编程语言」或「并行编程语言」的明确定义,自然也谈不上说哪一种语言可以被标上这种名字。如果非要说有,Erlang 大概算是唯一的一个:它是把多进程(当然它的进程和操作系统的进程概念还有差别)的构造和通讯内建在语言设施里的。其他语言多半将多进程或多线程的管理以函数库的形式存在。
很难说 Erlang 这种做法是好是坏。计算机程序设计语言的发展历史上,对功能的实现方式一直有两种争论:一种提倡在语言级别实现尽量少的实际功能,把它们推到库函数里面实现,比如 C++;一种则倾向于在语言级别实现各种常见功能,比如 Perl。两种做法各有利弊:内建于语言实现的好处是写法更简洁,但缺点是一旦实现有缺陷则无法替代;库函数方案正好相反,带来了功能上的灵活,却会导致语言复杂化。所以事实上,多数语言的设计者都做了权衡,只将某些确实常用的功能设施内建于语言。并行/并发作为一种功能也不例外,但像 Erlang 这样的处理,比较少见。
所谓「本质」不同,我倒是要反过来问一句——请问汇编到C,有什么「本质」不同?C 到 C++,有什么「本质」不同?说到底,我们还是在冯・诺伊曼的体系里,做的还是程序存储和程序执行,即使是目下号称的所谓无状态的「纯函数」语言,也不得不偷偷地用各种概念保留程序存储,只是让自己看上去似乎是无状态而已。我看不到从那时到现在,程序设计语言上有什么「本质」的变化,即使有,也不是程序设计语言能够反映出来的。
最后纠正题目中的几个错误: