Loading...

关于语言设计的五个问题

Original

2001 年 5 月

(这些是我在 2001 年 5 月 10 日麻省理工学院关于编程语言设计的圆桌讨论中做的一些笔记。)

1. 编程语言是为人类设计的。

编程语言 是人们与计算机交流的方式。计算机对任何明确的语言都一样 乐于接受。我们之所以有高级语言,是因为人们无法处理 机器语言。编程语言的意义在于防止我们脆弱的人类大脑被 大量细节所淹没。

建筑师知道,某些类型的设计问题比其他问题更具个人 色彩。最干净、最抽象的设计问题之一是设计桥梁。你的工作主要 是使用最少的材料跨越给定的距离。另一方面是设计椅子。椅子设计师必须花时间 思考人类的屁股。

软件也以同样的方式变化。为数据通过网络路由设计算法是一个 很好的抽象问题,就像设计桥梁一样。而设计编程语言则像设计 椅子:都是关于处理人类的弱点。

我们大多数人都不愿承认这一点。设计具有极高 数学优雅性的系统听起来对我们大多数人来说比迎合人类的弱点 更有吸引力。数学 优雅性确实发挥着作用:某些类型的优雅性使程序更容易理解。 但优雅本身并不是目的。

当我谈到语言必须设计成适合人类的弱点时, 我并不是说语言必须为糟糕的程序员设计。 事实上,我认为你应该为 最好的程序员 设计,但 即使是最优秀的程序员也有局限性。我不认为任何人 会喜欢用一种语言编程,在这种语言中,所有变量都是 字母 x 带有整数下标。

2. 为自己和你的朋友设计。

如果你看看编程语言的历史,你会发现很多最好的 语言都是为其作者自己使用而设计的,而 很多最糟糕的语言都是为其他人使用而设计的。

当语言为其他人设计时,它总是针对特定 的一群人:比语言设计者不那么聪明的人。 因此,你得到了一种贬低你的语言。Cobol 是最 极端的例子,但很多语言都渗透着这种精神。

这与语言的抽象程度无关。C 非常 底层,但它是为其作者使用而设计的,这就是 为什么黑客喜欢它。

为糟糕的程序员设计语言的论据是, 糟糕的程序员比优秀的程序员多。这可能是 真的。但那些少数优秀的程序员编写了不成比例的 大部分软件。

我感兴趣的是这个问题,你如何设计一种语言, 让最优秀的程序员喜欢?我恰好认为这与 问题相同,你如何设计一种好的编程 语言?但即使不是这样,它至少也是一个有趣 的问题。

3. 给程序员尽可能多的控制权。

许多语言 (尤其是那些为其他人设计的语言)具有 女家庭教师的态度:它们试图阻止你 做一些它们认为对你不好 的事情。我喜欢 相反的方法:给程序员尽可能多的 控制权。

当我第一次学习 Lisp 时,我最喜欢它的地方是 它把我视为平等的伙伴。在我之前学习的其他语言中, 有语言,还有我的 程序,用语言编写,两者是截然分开的。 但在 Lisp 中,我编写的函数和宏就像那些 构成语言本身的函数和宏一样。如果我想,我可以重写语言。 它与开源软件具有相同的吸引力。

4. 追求简洁。

简洁被低估,甚至被蔑视。 但如果你深入黑客的心灵,你会发现他们 真的很喜欢它。你听到黑客们怀念多少次 在,比如,APL 中,他们可以用几行代码做惊人的事情?我认为任何真正聪明的人真正 喜欢的东西都值得关注。

我认为几乎任何 你可以做的事情来使程序更短都是好的。应该有很多 库函数;任何可以隐式的都应该隐式; 语法应该尽可能简洁;甚至事物的名称 也应该简短。

不仅程序应该简短。手册也应该 薄一些。手册中很大一部分内容是用来澄清 和保留以及警告和特殊情况的。如果你强迫 自己缩短手册,在最好的情况下,你会通过修复 语言中需要如此多解释的东西来做到这一点。

5. 承认黑客是什么。

很多人希望黑客是 数学,或者至少像自然科学一样。我认为 黑客更像建筑。建筑是 与物理学相关的,因为建筑师必须设计 不会倒塌的建筑,但建筑师的实际目标是 建造伟大的建筑,而不是进行关于静力学的发现。

黑客喜欢做的是编写伟大的程序。 我认为,至少在我们自己的脑海中,我们必须记住,编写伟大的程序是 一件值得称赞的事情,即使这项工作 不能轻易转化为研究论文的传统智力 货币。从智力上来说,设计一种程序员喜欢的语言与设计一种 糟糕的语言一样有价值,这种语言体现了你 可以发表论文的某个想法。

1. 如何组织大型库?

库正在成为 编程语言中越来越重要的组成部分。它们也 越来越大,这可能很危险。如果找到 可以做你想做的事情的库函数所需的时间比 你自己编写它所需的时间更长,那么所有这些代码都无济于事 只会让你的手册变厚。(Symbolics 手册就是一个例子。)因此,我认为我们必须努力寻找组织 库的方法。理想的情况是,将它们设计成程序员 可以猜测哪个库调用会做正确的事情。

2. 人们真的害怕前缀语法吗?

这是一个开放 问题,因为我多年来一直在思考这个问题, 但仍然不知道答案。前缀语法对我来说似乎很自然, 除了可能用于数学。但可能是 Lisp 的很多 不受欢迎仅仅是因为它有一个不熟悉的语法。 是否要对此做些什么,如果是真的,则是另一个问题。

3. 服务器端软件需要什么?

我认为很多最令人兴奋的新应用程序将在未来 二十年内被编写出来,它们将是基于 Web 的应用程序,这意味着 运行在服务器上的程序,通过 Web 浏览器与你交流。为了编写这些类型的程序,我们可能需要一些 新东西。

我们需要的一件事是支持服务器端 应用程序发布的新方式。与桌面软件每年发布一两次大版本不同,服务器端应用程序以 一系列小的更改发布。你可能每天发布五到十次 版本。而且通常情况下,每个人都会使用最新的 版本。

你知道如何设计程序以使其可调试吗? 同样,服务器端软件也必须设计成可 更改的。你必须能够轻松地更改它,或者至少 知道什么是小的更改,什么是重大的更改。

另一件可能对服务器端 软件有用,令人惊讶的是,是延续。在基于 Web 的软件中, 你可以使用类似延续传递风格的东西来获得 子程序 的效果,在 Web 会话的本质上无状态的世界中。也许拥有真正的延续是值得的, 如果它不是太昂贵的话。

4. 还剩下哪些新的抽象有待发现?

我不确定 这是一个多么合理的希望,但我个人真的很想 做的事情是发现一个新的抽象——一些能够 像拥有头等函数或 递归甚至关键字参数一样产生重大影响的东西。这可能是一个不可能的 梦想。这些东西并不经常被发现。但我一直在 寻找。

1. 你可以使用任何你想要的语言。

编写应用程序 程序曾经意味着编写桌面软件。在桌面 软件中,有一种强烈的倾向,即用与操作系统相同的语言编写应用程序。因此,十年前, 编写软件几乎意味着用 C 编写软件。 最终,一种传统演变出来: 应用程序程序不能用不寻常的语言编写。 这种传统已经发展了很长时间,以至于非技术人员 比如经理和风险投资家也学会了它。

服务器端软件打破了整个模型。使用服务器端 软件,你可以使用任何你想要的语言。几乎没有人理解 这一点(尤其是经理和风险投资家)。 少数黑客理解这一点,这就是我们甚至听到 关于像 Perl 和 Python 这样的新兴语言的原因。我们没有听到 关于 Perl 和 Python 的原因是因为人们正在使用它们来编写 Windows 应用程序。

这对我们来说意味着什么,作为对设计编程语言感兴趣的人, 现在我们可能有一个真正的受众。

2. 速度来自分析器。

语言设计者,或者至少 语言实现者,喜欢编写生成快速 代码的编译器。但我认为这不是让语言对用户来说很快的原因。 Knuth 很久以前就指出,速度只在少数关键 瓶颈中很重要。任何尝试过的人都知道,你无法猜测 这些瓶颈在哪里。分析器是答案。

语言设计者正在解决错误的问题。用户不需要 基准测试来运行得快。他们需要的是一种语言,这种语言可以显示 他们自己的程序中哪些部分需要重写。这就是 速度在实践中产生的来源。因此,也许如果语言实现者将他们 本来花在编译器优化上的时间的一半花在编写一个 好的分析器上,那将是一个净收益。

3. 你需要一个应用程序来驱动语言的设计。

这可能不是一个绝对的规则,但似乎最好的语言 都是与它们被用来编写的某个应用程序一起发展起来的。C 是由需要它进行系统编程的人编写的。 Lisp 的开发部分是为了进行符号微分, 麦卡锡非常渴望开始,甚至在 1960 年关于 Lisp 的第一篇论文中,他就开始编写微分 程序。

如果你的应用程序解决了一些新问题,那就更好了。 这将倾向于驱动你的语言具有程序员需要的 新功能。我个人对编写 一种适合编写服务器端应用程序的语言感兴趣。

[在小组讨论中,Guy Steele 也提出了这一点,并建议 应用程序不应包括编写你的语言的编译器,除非你的语言 恰好是为编写编译器而设计的。]

4. 一种语言必须适合编写一次性程序。

你知道一次性程序是什么:你快速编写的东西,用于 一些有限的任务。我认为如果你环顾四周,你会发现 很多大型严肃的程序都是从一次性程序开始的。我 不会感到惊讶,如果 大多数 程序都是从一次性程序开始的。因此,如果你想设计一种适合 编写一般软件的语言,它必须适合编写一次性程序,因为这是大多数软件的幼虫阶段。

5. 语法与语义相关。

传统上认为 语法和语义是完全分开的。这听起来很震惊,但它们可能不是。 我认为你想要的东西可能与你表达它的方式有关。

我最近和 Robert Morris 谈话,他指出 运算符重载在具有中缀 语法的语言中是一个更大的优势。在具有前缀语法的语言中,你定义的任何函数 实际上都是一个运算符。如果你想为 你创建的一种新的数字类型定义一个加法,你只需定义一个新的函数 来添加它们。如果你在具有中缀语法的语言中这样做, 重载运算符的使用和函数调用之间存在很大的外观差异。

1. 新的编程语言。

早在 20 世纪 70 年代, 设计新的编程语言很流行。最近 它已经不再流行了。但我认为服务器端软件将使新的 语言再次流行起来。使用服务器端软件,你可以 使用任何你想要的语言,因此,如果有人确实设计了一种语言, 这种语言实际上看起来比其他可用的语言更好,那么就会有人 冒险使用它。

2. 分时。

Richard Kelsey 在上次小组讨论中将其作为一种时机已到的想法提出,我完全同意他的观点。 我的猜测(以及微软的猜测,似乎是)是,很多计算 将从桌面转移到远程服务器。换句话说, 分时又回来了。我认为需要在语言级别上支持 它。例如,我知道 Richard 和 Jonathan Rees 在 Scheme 48 中做了很多工作来实现进程 调度。

3. 效率。

最近,人们开始觉得计算机 终于足够快了。我们越来越常听到 关于字节码,这至少对我来说意味着我们觉得我们有 足够的周期。但我认为我们不会有,使用服务器端 软件。有人必须为运行 软件的服务器付费,而他们每台机器可以支持的用户数量将是其资本成本的除数。

因此,我认为效率很重要,至少在计算 瓶颈中很重要。快速执行 i/o 将尤其重要, 因为服务器端应用程序执行大量的 i/o。

最终,字节码可能不是一个胜利。Sun 和 微软似乎正在进行一场关于字节码的战斗。 但他们这样做是因为字节码是一个 方便的地方,可以将自己插入到进程中,而不是因为 字节码本身是一个好主意。最终,这个 整个战场可能会被绕过。这将很有趣。

1. 客户端。

这只是一个猜测,但我猜测 大多数应用程序的获胜模式将纯粹是基于服务器的。 设计在每个人都会 拥有你的客户端的假设下工作的软件,就像设计一个在每个人都会 诚实的假设下工作的社会一样。这当然很方便,但 你必须假设它永远不会发生。

我认为将会有越来越多的设备拥有某种 Web 访问权限,而你所能假设的关于它们的一切就是 它们可以支持简单的 html 和表单。你的手机上会有一个 浏览器吗?你的掌上电脑里会有一个电话吗?你的黑莓手机会得到一个更大的屏幕吗?你能够 在你的 Game Boy 上浏览 Web 吗?你的手表?我不知道。 而且我不必知道,如果我押注 所有东西都在服务器上。拥有所有 服务器上的大脑 更加健壮。

2. 面向对象编程。

我知道这是一个 有争议的问题,但我认为面向对象编程 并不是什么大不了的事情。我认为它对于某些类型的 需要这种特定数据结构的应用程序来说是一个很好的模型, 比如窗口系统、模拟和 CAD 程序。但我没有 看到为什么它应该成为所有编程的模型。

我认为人们在大公司喜欢面向对象编程的部分原因是,它产生了大量看起来像工作的东西。 一些可能自然地表示为,比如,一个整数列表,现在可以表示为一个类,它具有各种 支架和喧嚣和繁忙。

面向对象编程的另一个吸引力是,方法为你提供了一些 头等函数的效果。但这对 Lisp 程序员来说已经是老生常谈了。当你拥有真正的头等函数时,你可以 根据手头的任务以任何合适的方式使用它们, 而不是将所有东西都强迫到类和方法的模具中。

我认为,这对语言设计意味着,你不应该 将面向对象编程构建得太深。也许 答案是提供更通用、更底层的东西,让人们设计 他们想要的任何对象系统作为库。

3. 委员会设计。

让你的语言由委员会设计是一个很大的陷阱, 不仅仅是因为每个人都知道的原因。每个人 都知道委员会往往会产生笨拙、不一致的设计。 但我认为更大的危险是他们不会冒险。 当一个人负责时,他可以冒险 委员会永远不会同意的风险。

设计一种好的语言是否需要冒险? 很多人可能会怀疑 语言设计是一个应该相当 接近传统智慧的地方。我敢打赌这不是真的。 在人们做的其他所有事情中,回报与风险成正比。 为什么语言设计应该有什么不同?