一种语言
2007 年 7 月 28 日
我们是否应该努力在开发工作中只使用一种语言?
在过去十年的很大一部分时间里,企业软件世界的时尚是专注于一种用于软件开发工作的标准语言。许多开发组织努力将其所有工作都用 Java(或 C#/VB)完成。
这样做的理由是,开发人员发现很难精通多种语言。坚持使用单一语言可以降低学习负担,尤其是在招聘新人时。
这有一定的道理,但也缺少很多东西。编程环境部分是语言,但也与语言和框架有关。更大的框架,Hibernate、Struts、ADO,与语言一样具有挑战性,即使你用单一宿主语言对它们进行编程。通常,用宿主语言表达你需要的困难程度非常尴尬,以至于许多框架诉诸于配置文件,这些配置文件实际上是用 XML 编写的外部领域特定语言 - 这为它们添加了一丝 80 度的丑陋。
对于许多开发人员来说,单一语言的概念是缺乏专业精神的标志。这最好地体现在务实程序员的建议中,即每年学习一门新语言。这里的重点是,编程语言确实会影响你对编程的思考方式,学习新语言可以帮助你以不同的方式思考解决问题。(重要的是要学习截然不同的语言,以便从中学到好处。Java 和 C# 太相似了,不值得一提。)
我同意 prags 在这里给出的建议,就像在大多数事情上一样。但我也能理解学习新语言的开销。我个人的脚本几乎都是用 Ruby 编写的,我一直不愿意尝试其他像 Python、Groovy 或 PowerShell 这样的合理替代方案。并不是说这些替代方案很难使用,而是因为我对 Ruby 太熟悉了,以至于我不得不去查阅其他替代方案的用法。
这里重要的是,当我编写这些脚本时,我并没有操作新的抽象。我所做的很多事情都是处理文本、文件系统以及 XML 或 YAML 的大块内容。如果我需要承担一个相当大的新抽象,学习它作为库的成本实际上与学习一种语言来操作它的成本相差无几。如果我想为显示指定一个有向图结构,学习Graphviz 的 Dot 语言几乎不比学习一个新的 Ruby 库更费事。
使用 DSL 而不是库可以为我们提供更好的方法来操作我们的抽象。这使得我们更容易看到我们写了什么,并揭示我们的意图。API 就像声明一个词汇表,DSL 添加了一个语法,允许你写连贯的句子。
这个论点对于 DSL 来说很有力,但它也适用于通用语言吗?如果你正在使用 Java(或者很快的 C#),现在 Ruby 在你的平台上可用,那么使用它是否有意义呢?
过去十年见证了基于内存管理的 C 语言的兴起。人们发现,尽管多年来一直持怀疑态度,但内存管理使生活变得足够好,以至于在企业界值得放弃 C 和 C++。一个通用的平台和语言也让人们远离了像 Powerbuilder 和 Delphi 这样的专有封闭花园。
现在出现了类似的问题。现代脚本语言是又向前迈进了一步吗?我们是否更喜欢它们精心选择的简洁性?我一次又一次地听到经验丰富的 Java 和 C# 开发人员报告说,他们在 Ruby 中更有效率 - 这就是我一直鼓励使用 Ruby 的原因。如果在未来几年中,其他语言也出现类似的报告,我不会感到惊讶。
十年前,我在 OOPSLA 96 上与我的老朋友汤姆·哈德菲尔德交谈。Java 的兴起显而易见,很明显 Smalltalk 的未来注定要失败。尽管我热爱 Smalltalk,但我还是相当坦然。我觉得 Java 给人们提供了他们所需要的足够的东西;虽然它不像 Smalltalk 那样好,但它比 C++ 有了很大的改进,尤其是在内存管理方面,足以让我满意。汤姆不同意,他觉得 Smalltalk 的表达能力有根本的不同,你可以在代码中更好地直接捕捉你正在做的事情的意图 - 缩小了领域知识和编程之间的差距。
在接下来的几年里,我逐渐认识到汤姆是对的。在花了几年时间在花括号的世界里之后,Ruby 让我想起了我错过了什么。阅读 Ruby 代码有一种清晰度,这使得它成为一个更容易使用的媒介,尽管工具不如其他语言好。我对 Smalltalk 的坚守者比以前更有同情心,尽管我已经很久没有因为愤怒而打开一个镜像了。
那么,我们是否回到了 80 年代后期和 90 年代初期的语言混乱?我认为我们将看到多种语言在喋喋不休,但会有一个重要的区别。在 80 年代后期,很难让语言紧密地互操作。如今,人们非常重视创建允许不同语言紧密共存的环境。脚本语言传统上与 C 语言有着密切的关系。在 JVM 和 CLR 平台上,人们付出了很多努力来实现互操作性。人们在库上投入了太多,以至于一种语言无法忽视它们。
因此,我的感觉是,我们将看到多个语言在项目中使用,人们会根据语言的功能来选择语言,就像人们现在选择框架一样。我同意尼尔的观点,我们正在进入一个多语言编程的时代。