选择编程语言后的人类生活,只有少数几件事是可以确定的

译者:阮一峰

很难预测一百年后人类的生活会是什么样子,只有几件事是确定的。届时,汽车将具备低空飞行能力,城市规划规定将放宽,建筑物可建至数百层,街道上终日见不到阳光,女性都将学习自我防备。本文只想讨论其中一个细节:一百年后,人们会用什么语言来开发软件?

为什么这个问题值得思考?原因不是我们最终会使用这些语言,而是如果幸运的话,我们从现在开始就可以使用这些语言了。

选择编程语言进化的支柱

在我看来,编程语言和生物物种一样,都有进化的主线,很多分支最终都会成为进化的死胡同。这种现象已经发生了。Cobol 语言曾经很流行,但似乎没有后续的语言继承了它的思想。就像尼安德特人一样,进化之路走到了尽头。

我预测 Java 也会这样做。有人写道:“你怎么能说 Java 不会成功?它已经成功了。” 我认为这取决于你的成功标准是什么。如果标准是出版的书籍数量,或者认为学习Java会找到工作的大学生数量,那么Java确实成功了。当我说 Java 不会成功时,我的意思是它和 Cobol 一样,已经走到了尽头。

这只是我的猜测,可能不正确。这里的重点不是看不起Java,而是提出编程语言存在进化脉络,以此引导读者思考,某种语言在整个进化过程中的位置在哪里?我之所以提出这个问题,不是为了让后人感叹一百年后的我们曾经多么睿智,而是为了找到进化的脊梁。它将启发我们选择那些靠近主干的语言,这对当前的编程最有利。

只要有可能,选择进化骨干可能是最好的解决方案。如果你不幸选错了一个尼安德特人计算机能直接识别的语言是,那就太糟糕了。你的对手克罗马侬人会不时来攻击你并偷走你所有的食物。

这就是为什么我想知道一百年后的编程语言会是什么。我不想赌错。

编程语言的聚合

编程语言的进化与生物进化还是有区别的,因为不同分支的语言是汇合的。例如,Fortran 分支似乎正在与 Algol 的继任者融合。理论上,不同的生物物种有可能会聚,但可能性很低,所以想必它从未真正发生过。

编程语言能聚合的一个原因是它的概率空间比较小,另一个原因是它的突变不是随机的。语言设计师总是有意识地借鉴其他语言的设计理念。

对于语言设计者来说,识别编程语言的进化路径特别有用,这样语言就可以这样设计。此时,识别进化骨干不仅可以帮助识别现有的优秀语言,还可以将其作为设计语言的指南。

选择具有最小和最干净内核的编程语言

任何编程语言都可以分为两个主要部分:原始运算符集(扮演公理的角色)和运算符之外的另一部分(原则上可以用原始运算符表示)。

在我看来,基本运算符是语言寿命的最重要因素。其他因素都不是决定性的。这有点像买房子时首先要考虑位置。以后有其他地方的问题可以弥补,但是地理位置是不能改变的。

仔细选择公理是不够的,还必须控制它的规模。数学家总是认为公理越少越好,我认为他们达到了目标。

您查看一种语言的内核并考虑可以省略哪些部分,这至少是一种有用的培训。在漫长的职业生涯中,我发现冗余代码会导致更多的冗余代码,不仅在软件中,而且在像我这样的懒人身上,我发现这个命题在床底下和房间角落里都是正确的,一件垃圾会产生更多垃圾。

我的判断是,那些内核最小、最干净的编程语言存在于进化主干上。语言的内核设计得越小越干净,它的弹性就越大。

当然,猜测一百年后人们会使用什么编程语言本身就是一个很大的假设。也许一百年后,人类会停止编程,或者只是告诉计算机该做什么,计算机就会自动完成。

不过,到目前为止,计算机智能还没有取得太大进展。我猜一百年后,人们仍然会使用类似的程序来指挥计算机。可能有一些我们今天需要编程解决的问题,当时不需要编程,但我认为会有很多与今天相同的编程任务。

你可能认为只有自以为是的人才会预测一百年后的技术。但是,不要忘记,软件开发的历史已经走过了 50 年。在这 50 年里,编程语言的演进其实一直很慢,所以期待一百年后的语言并不是空灵的想法。

编程语言发展缓慢的原因在于它们并不是真正的技术。语言只是一种写作方式,而程序是对计算机应如何以书面形式解决您的问题的严格遵守规则的描述。因此,编程语言的发展速度更像是数学符号的发展速度,而不是真正的技术(如交通或通信技术)的发展速度。数学符号的演变是一个缓慢的、渐进的变化,而不是真正技术的飞跃。

无论一百年后的计算机是什么样子,我们基本上可以得出结论,它们会快得多。如果摩尔定律仍然成立,一百年后,计算机将是 18 次方的 74 倍(73786976294838206464 次)。这是难以想象的。但更现实的预测并不是速度会提升这么多,而是摩尔定律最终会失效。不管它是什么,如果它每 18 个月翻一番,它最终很可能会达到极限。但毫无疑问,当时的计算机比现在快得多。即使它最终只快了一百万倍,这也将大大改变编程的基本规则。在其他条件相同的情况下,现在被认为很慢的语言(即,

到那时,仍然会有应用程序需要非常高的速度。我们希望计算机解决的一些问题,其实是计算机本身造成的。例如,计算机处理视频的速度取决于生成这些视频的另一台计算机。此外,还有一些问题本身需要无限快的处理能力,例如图像渲染、加密/解密、模拟运算等。

由于在现实中一些应用程序本身效率较低,而另一些应用程序则耗尽了硬件提供的所有计算能力,拥有更快的计算机意味着编程语言必须处理更多的极端情况,涵盖更广泛的效率要求。我们已经看到了这种情况。用新语言编写的一些最热门的应用程序按照几十年的旧标准,对硬件资源的浪费是惊人的。

有这种现象的不仅仅是编程语言,实际上是一种普遍的历史趋势。随着技术的进步,每一代人都在做上一代人认为是浪费的事情。30 年前的人们看到我们今天使用长途电话的随意性会感到震惊。100年前,如果看到一个普通的包裹可以从波士顿经孟菲斯寄出,在一天之内到达纽约,那会更令人震惊。

关于“浪费”

我已经预测到未来硬件性能大幅提升后会发生什么。新增加的算力会被浪费掉。

在我学习编程的时候,计算机还是很稀有的。记得当时用的电脑型号是TRS-80,内存只有4K。为了将 BASIC 程序加载到内存中,我不得不删除源代码中的所有空格。我无法忍受可怕的低效软件不断重复一些愚蠢的计算并占用硬件的所有计算能力的想法。然而,我的这种反应是错误的。我就像一个穷人家的穷孩子,一听到钱就舍不得花钱。即使这笔钱用于重要场合(比如去医院),也很难接受。

某些浪费真的很恶心。例如,有些人讨厌 SUV(运动型多功能车),即使他们使用可再生和清洁能源,因为 SUV 来自一个令人讨厌的想法(如何让小型货车看起来更有男子气概)。然而,并不是所有的浪费都是坏的。现在电信基础设施这么发达,到时候打长途电话有点浪费。如果你有足够的资源,你可以把长途和市话当作一回事,一切都会变得更容易。

废物可分为好废物和坏废物。我对良好的浪费感兴趣,即更简单的设计以获得更多的钱。那么,问题就变成了如何利用更强大的性能最好地“浪费”新硬件?

追求速度是人类根深蒂固的愿望。当你看着像电脑一样的小玩意儿时,你会忍不住希望程序运行得越快越好。要克制这种欲望,确实需要下一番功夫。在设计编程语言时,我们应该有意识地问自己,什么时候可以为了一点方便而放弃一些性能。

正确的方式

存在许多数据结构的原因与计算机的速度有关。例如,今天的许多语言都有字符串和列表。从语义上讲,字符串或多或少可以理解为列表的子集,其中每个元素都是一个字符。那么,为什么需要将字符串作为数据类型进行分隔呢?绝对可以不这样做。字符串的存在只是为了提高效率。但是,这种为了加速运算而使编程语言的语义变得非常复杂的行为是非常不可取的。编程语言设置字符串似乎是过早优化的一个例子。

如果我们把一种语言的内核想象成一些基本公理的集合,那么在内核中加入冗余公理只是为了提高效率而没有带来表现力的提升,那一定是一件坏事。是的,效率很重要,但我不认为修改语言设计是提高效率的正确方法。

正确的做法应该是将语言的语义与语言的实现分开。语义上不需要列表和字符串,只需一个列表就足够了。并在实现中做好编译器的优化工作,使其在必要时将字符串视为连续字节。

对于大多数程序来说,速度并不是最关键的因素,所以你通常不需要担心这种硬件级别的微管理。随着计算机变得越来越快,这一点变得越来越明显。

低效≠坏

对实现的限制较少的语言设计也使程序更加灵活。语言规范的变化不仅是不可避免的,而且是合理的。通过编译器的处理,按照以前的规范开发的软件将照常运行,从而提供了灵活性。

“essay”这个词来自法语动词essayer,意思是“尝试”。从最初的意义上说,论文是当你写一篇文章试图弄清楚一些事情的时候。软件也是如此。我认为一些最好的软件就像论文一样,也就是说,当作者真正开始编写软件时,他们并不真正知道自己最终会写出什么。

Lisp 中的黑客早就明白数据结构灵活性的价值。当我们编写程序的第一个版本时,我们倾向于将所有内容都作为一个列表来处理。所以,这些初始版本的效率可能出奇的低,你必须努力让自己不去优化它们,就像吃牛排一样,你必须努力停止思考牛排是从哪里来的,至少对我来说是这样说的。

一百年后程序员最需要的编程语言是一种允许您轻松编写程序的第一个版本的编程语言,即使它非常低效(至少在我们今天看到的情况下)。他们会说他们想要的是一种易于学习的编程语言。

低效的软件不等于糟糕的软件。让程序员什么都不做的语言真的很糟糕。真正的低效率是浪费程序员的时间而不是机器的时间。随着计算机变得越来越快,这将变得越来越明显。

我们可以放弃基本的数据类型吗?

我认为放弃字符串类型是一个可以接受的想法。Arc 语言已经做到了这一点,而且似乎运行良好。一些过去用正则表达式难以描述的操作,现在可以用回归函数很容易地表达出来。

图片[1]-选择编程语言后的人类生活,只有少数几件事是可以确定的-老王博客

这种数据结构扁平化的趋势将如何发展?我非常努力地想象我得到的结果甚至让我自己都感到惊讶的可能性。例如,数组会消失吗?毕竟数组只是哈希表的一个子集,其特点是数组的键都是整数向量。此外,哈希表本身会被列表替换吗?

还有比这更惊人的预言。从逻辑上讲,不需要为整数设置单独的表示,因为它们也可以看作列表,而整数 n 可以用 n 个元素的列表来表示。这仍然可以完成数学运算计算机能直接识别的语言是,但效率低得无法忍受。

编程语言会进化到丢弃基本数据类型之一的整数吗?我问这个并不是真的要你认真思考这个问题,而是更多地向未来敞开心扉。我只是提出一个假设的情况:如果不可抗拒的力量遇到不可移动的物体会发生什么。本文专门针对:当一种难以想象的低效语言遇到难以想象的强大硬件时会发生什么。我认为删除整数类型没有任何问题。未来相当漫长。如果我们想减少语言内核中基本公理的数量,我们不妨再看看,如果时间变量 t 趋于无穷大,会发生什么。一百年是一个很好的指标,如果你认为一个想法在一百年后可能仍然无法接受,

让我明确一点,我并不是说所有整数运算都用列表实现,而是语言的内核(不涉及任何编译器实现)可以这样定义。实际上,任何进行数学运算的程序都可能以二进制表示数字,但这是编译器的优化,而不是语言内核语义的一部分。

另一种消耗硬件性能的方法是在应用软件和硬件之间放置许多软件层。这也是我们看到的一个趋势,很多新兴语言被编译成字节码。比尔·伍兹曾经对我说过,根据经验,软件每增加一层解释就会慢一个数量级。但是,额外的软件层可以使编程变得灵活。

Arc语言的原版就是一个极端的例子,它有很多层,速度很慢,但确实带来了相应的好处。Arc 是一个典型的“元循环”解释器,在 CommonLisp 之上开发,很像 John McCarthy 在他的经典 Lisp 论文中定义的 eval 函数。Arc解释器只有几百行代码,很容易理解和修改。我们使用的 Common Lisp 版本是 CLisp,它本身是在另一个字节码解释器之上开发的。所以,我们有两层解释器。顶层的效率低得惊人,但语言本身是可用的。我承认它几乎无法使用,但它确实有效。

使用多层形式开发

即使对于应用程序,使用多层进行开发也是一项强大的技术。自下而上的编程方法意味着将软件划分为多个层,每个层都可以作为其上层的开发语言。这种方法往往会产生更小、更灵活的程序。这也是通往软件圣杯的最佳途径——可重用性。根据定义,语言是可重用的。在编程语言的帮助下,您的应用程序以这种多层形式开发得越多,它的可重用性就越好。

可重用性的概念或多或少与 1980 年代面向对象编程的兴起有关。无论你如何寻找证据,都不可能将两者完全分开。一些使用面向对象编程开发的软件确实是可重用的,不是因为它使用了面向对象编程,而是因为它的开发方法是自下而上的。以函数库为例。它们是可重用的,因为它们是语言的一部分,而不是因为它们是面向对象或其他编程方法。

顺便说一句,我不认为面向对象编程在未来会消亡。我不认为这种编程方法实际上给优秀的程序员带来了很多好处,除了某些特定领域,但它对大公司有不可抗拒的吸引力。面向对象编程为您提供了一种可持续开发意大利面条式代码的方法。通过不断的打补丁,它可以让你把软件做的越来越大。大公司总是倾向于以这种方式开发软件。我希望在一百年后也是如此。

谈并行计算

既然谈未来,不如谈并行计算,因为看来并行计算是为未来而存在的。不管你怎么想,并行计算似乎是未来生活的一部分。

未来会实现吗?在过去的二十年里,人们一直在说并行计算指日可待。但是,到目前为止,它还没有对编程实践产生太大影响。这是真的吗?芯片设计人员已经必须考虑到这一点,为多 CPU 计算机开发系统软件的程序员也是如此。

然而,真正的问题是,并行计算可以达到什么抽象级别?它会影响一百年后开发应用软件的程序员吗?或者它只是编译器作者需要考虑的事情,而在应用程序的代码中根本找不到?

一种可能性是,在大多数可以使用并行计算的情况下,人们会放弃使用并行计算。虽然我的一般预测是未来的软件将浪费大部分增加的硬件性能,但并行计算是一个特例。我认为随着硬件性能的惊人改进,如果你明确表示你想要并行性,你肯定可以得到它,但通常你不会使用它。这意味着,除了一些特殊的应用,一百年后的并行计算不会是那种大规模的并行计算。我希望对于普通程序员来说,这更像是复制一个进程并让多个进程在后台并行运行。

这是在编程中很晚才做的事情,属于程序的优化,类似于当你想开发一个特定的数据结构来替换现有的数据结构时。程序的第一个版本通常会忽略并行计算提供的各种好处,就像编程开始时忽略特定数据结构给您带来的好处一样。

除了一些特定的应用软件,一百年后并行计算不会很流行。如果应用软件真的大量使用并行计算,这就是过早的优化。

100年的语言数量

一百年后会有多少种编程语言?近来出现了大量的新语言。提高硬件性能是原因之一,它允许程序员根据使用目的在速度和编程易用性之间做出不同的权衡。如果这是未来的方式,那么一百年后,强大的硬件只会让语言的数量更多。

但是,另一方面,一百年后可能只有几种通用语言。部分基于我的乐观,我相信在未来,如果你的工作真的很好,你可能会选择一种方便开发的语言。用这种语言编写的软件的第一个版本速度很慢,只有在优化编译器后才会有所改进。既然我有这种乐观,我还有一个预测要做。一些语言可以达到机器的最大效率,而另一些语言的运行速度刚好够慢。我预测一百年后,在这个差距的每个点上都会有相应的编程语言。

由于这种差距正在扩大,性能分析器将变得越来越重要。目前,性能分析还没有受到太多关注。许多人似乎仍然认为,更快的程序的关键是开发生成更快代码的编译器。代码效率和机器性能的差距越来越大,我们会越来越清楚地看到,提高应用软件速度的关键是要有一个好的性能分析器来帮助指导程序开发。

我说未来可能只有几种通用语言,但没有计算特定领域使用的“小众语言”。我认为这些嵌入式语言的想法很棒并且会蓬勃发展。但我判断这些“小众语言”会被设计成相当薄的一层,让用户一眼就可以看到作为底层基础的通用语言,从而减少学习时间和使用成本。

谁将设计这些未来的语言?过去 10 年最令人兴奋的趋势之一是 Perl、Python 和 Ruby 等开源语言的兴起。语言设计已被黑客接管。目前尚不清楚这是好是坏,但势头令人鼓舞。例如,Perl 有一些很棒的创新。但是,它也包含一些非常糟糕的想法。对于具有攻击性和探索性的语言来说,这也是正常的。以目前的变化速度,只有天知道 Perl 一百年后会是什么样子。

有句话说,自己做不到,就当老师。这在语言设计中并不成立,我认识的一些最好的黑客都是教授。但是,确实有很多事情是老师做不到的。研究职位对黑客施加了一些限制。在任何学术领域,都有一些课题可以做,而另一些则不能。不幸的是,这两种类型的主题之间的区别通常是基于它们在编写时看起来有多深,而不是它们对软件行业的发展是否重要。也许最极端的例子是文学,文学研究者的任何成就对文学创作者几乎没有影响。

虽然科学状况稍微好一些,但研究人员可以做的主题与可以帮助设计好的语言的主题之间的交叉点非常小。例如,关于变量类型的论文似乎层出不穷,尽管静态类型语言似乎并不真正支持宏(而且在我看来,不支持宏的语言不值得使用) .

新语言更多地以开源项目的形式出现,而不是研究项目。这是语言的发展趋势。另一个趋势是新语言的设计者更多是需要自己使用的应用软件作者,而不是编译器作者。这似乎是一个很好的趋势,我希望它会继续下去。

摆脱思维定势

一百年后的物理学基本上是无法预测的。但计算机语言不同,理论上似乎有可能在一百年后开始设计一种新的语言来吸引用户。

设计一门新语言的方法之一是只编写您想要编写的程序,无论是否存在编译器或支持它的硬件。这是假设您可以使用无限的资源。无论是今天还是一百年后,这样的假设似乎都是合理的。

你应该写什么程序?不管怎样,只要它能让你用最少的努力写出来。但是请注意,这必须在您的思维不受当前使用的编程语言影响的情况下完成。这种影响无处不在,需要付出很多努力才能克服。你可能认为像人类这样的懒惰生物喜欢以最少劳动强度的方式编写程序是很自然的。但事实上,我们的思维往往可能仅限于一种现有的语言,只能以一种看起来比该语言更简单的形式出现,它对我们思维的约束作用可能会大得惊人。新语言必须自己去发现,而不是让你沉迷的思维定势。

简洁地编写程序

使用程序的长度作为其工作量的近似值是一种有用的技术。这里的程序长度当然不是字符数,而是各种句法元素的总长度,基本上就是整个解析树的大小。可能不能说最短的程序是写的最省力的程序,但是当你专注于简洁而不是松散地编写程序时,你就更接近于省力的目标,你的生活就会多更轻松。所以,设计一门语言的正确方法是,看看一个程序,问问自己你是否可以把它写得更短一点?

事实上,一百年后用虚构语言编写程序的可靠性取决于您对语言内核的估计是否足够准确。常规排序,现在就可以写了。但是,很难预测一百年后的语言中会使用哪些库。很可能许多图书馆的目标领域甚至还不存在。例如,如果 SETI@home 项目成功,我们将需要一个函数库来与外星人交流。当然,如果外星文明高度发展到可以以 XML 格式交换信息的地步,那么就不需要新的函数库了。

在另一个极端,我认为今天你可以在一百年后设计一个语言内核。事实上,根据一些人的说法,大多数语言内核都是在 1958 年设计的。

你今天想用吗

100年后的语言?

如果一百年后我们可以使用一种编程语言,我们会用它编程吗?看过去,知道现在。如果今天的编程语言在 1960 年就可以使用,那么当时的人们会使用它们吗?

在某些方面,答案是否定的。今天的编程语言所依赖的硬件在 1960 年是不存在的。比如在 Python 这样的语言中,正确的缩进在编写时很重要,但是 1960 年代的计算机没有显示器,只有打印机终端,所以不会写起来不流畅。

但是,如果你排除这些因素(你可以假设,我们只在纸上编程),1960 年代的程序员会喜欢用今天的语言编程吗?

我想他们会的。一些缺乏想象力的人,深受早期编程语言思想的影响,可能会发现这是不可能的。(如果没有指针运算,如何复制数据?没有 goto 语句如何实现流程图?)但我认为当时最聪明的程序员可以轻松使用今天的大多数语言,假设他们可以掌握它。

如果一百年后我们可以拥有一门编程语言,那么至少它可以用来编写好的伪代码。我们会用它来开发软件吗?因为一百年后的编程语言需要为某些应用程序生成快速代码,它很可能会生成可以在我们的硬件上以可接受的速度运行的代码。一百年后,我们可能不得不比用户优化语言多一点,但总的来说,它仍然应该给我们带来净收益。

现在试着写!

现在,我们的两个观点是:(1)一百年后的编程语言理论上可以设计到今天;(2)如果今天可以设计出这样的语言,很可能适合编程,并产生更好的结果。如果我们把这两个角度联系起来,那么就会出现一些有趣的可能性。为什么不从现在开始,尝试在一百年后编写一门编程语言呢?

当你设计你的语言时,记住这个目标是值得的。学习驾驶时,要记住的一个原则是直行,而不是将身体与绘制在地面上的分界线对齐,而是瞄准远处的一个点。即使您的目标只有几米远,这也是正确的。我认为我们在设计编程语言时也应该这样做。

本文节选自《黑客与画家——硅谷创业之父保罗格雷厄姆选集》一书,原标题为《一百年后的编程语言》。

简介:本书是硅谷创业之父保罗格雷厄姆的散文集。主要介绍黑客的爱好和动机,也就是优秀的程序员。它讨论了黑客的成长,黑客对世界的贡献,编程语言和黑客的工作方法。都是对计算机时代一些话题感兴趣的人。本书的内容不仅有助于理解计算机编程的本质、互联网行业的规则,还能帮助读者了解我们的时代,迫使读者独立思考。返回搜狐,查看更多

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论