本文要点
- .NET 现在的战略就是对于.NET Core 的跨平台开发,而.NET Standard 2.0 补充了缺失的部分。
- 简化跨平台工具,并帮助社区消除混淆是促使人们采纳.NET Core 和.NET Standard 的下一步。
- Roslyn 对.NET 有着重大影响,可以帮助新的功能更快交付。Roslyn 还让 Microsoft 之外的开发人员使用,来创建基于其公共 APIs 的自己的工具。
- .NET 社区现在热衷于开源,并越来越多地投入于编译器和系统库。
.NET 生态系统在过去的一年中发生了很多事情。在几个方面发展非常迅速:Xamari、UWP、.NET Core、.NET native、F#和开源等等。
如果要关注细节,那大的景象难以描绘。因为在每个方面都有新的动作:跨平台、云、移动、Web 应用和通用应用。开发人员都想知道这一切会造成什么改变,要实现改变必须要做些什么。
小组成员:
- Richard Lander,Microsoft .NET 团队首席项目经理
- Phillip Carter,Microsoft .NET 团队项目经理
- Phil Haack,GitHub 工程总监
- Miguel de Icaza,Microsoft 杰出工程师
InfoQ:.NET 及其语言将向哪里发展?会面临到什么挑战?
Richard Lander:通过观察目前广泛支持.NET 的设备和操作系统,还有最近的.NET Core,你就可以展望到.NET 的未来。你可以使用.NET 构建任何类型的应用程序,包括移动、Web、桌面以及 IoT。有趣的是,.NET 在很小一组开发平台上,但可以在许多平台上运行,具有很高的生产力和不断发展的语言、工具和企业支持。总之,这就是我们对 NET 的观点。
选择开源.NET Core 对.NET 产生了巨大的影响。我们看到大量的开源开发者参与到.NET
Core 和相关项目中来,.NET 相关活动在 GitHub 也快速上升。许多企业对.NET 的重大兴趣和认真参与也让我们感到非常惊讶。一些大的公司也加入了.NET 基金会,比如说 Samsung 和 Google。我们很高兴能看到其他很多企业表态:“.NET 对我们的业务非常重要,我们需要更多参与到其中”。我们将会继续开放和协作,采取更多方式来提升.NET。2016 年,Visual Studio for Mac 的推出是很大的惊喜。它包括 Xamarin 和 ASP.NET Core 的工具。Visual Studio for Mac 这款产品也表明了 Microsoft 的态度,就是我们正在认真促进跨平台开发。我们还有 Windows、Mac 和 Linux 平台的免费工具可以选择,因此想要开始使用.NET 非常简单。
遇到的挑战是想要让人们意识到.NET 不仅仅只是属于 Windows 平台下的,它已然变为了你下一个项目可以使用的值得信赖的跨平台开发选择。我们在过去几年内做了一些巨大的改变,比如获取 Xamarin,开源.NET Core 并搭建跨平台工具支持。我们还有很多工作要做,才能让人们对产品产生兴趣,这是前进的关键点。
Philip Carter:对于.NET 来说,现在最大的焦点莫过于.NET Standard Library 2.0 和尽可能多使用容器技术(例如 Docker)的经验。.NET Standard Library 2.0 成就了绝大多数跨平台.NET APIs,并为开发人员刨根知底他们所编写的代码提供了一种简单的方法。如果你依赖的唯一.NET APIs 来自.NET Standard Library,那可以确保在.NET 运行时你的代码能够在任何地方运行,而你不需要付出额外的工作。同理 NuGet 包也是一样的,如果你的系统依赖于.NET Standard Library,它可以在任何其他地方运行。从代码共享的角度来看这是非常重要的,甚至它对于长期的灵活性也非常重要。需要目标 Linux?你所有使用.NET Standard Library 的代码都在那里运行。我们也非常重视容器,希望你能非常容易地将代码部署到容器,因此我们正在构建工具来实现这一点。
对于.NET 语言,我们正在努力为我们的语言创造开箱即用的工具。在即将发布的 Visual Studio 中我们提供了一些具有生产力的功能,在未来我们也会构建更多的工具。在语言功能方面,C#和 Visual Basic 将着重于继续添加 F#中已有的函数式编程功能,比如基于表达式的模式匹配和记录以及可区分联合类型。不可空性也是我们感兴趣的一个重大领域。F#可能更关注于更好的 IDE 工具,它已经具备了前面提到的这些功能,但是缺乏与 C#和 Visual Basic 一样的质量工具体验。总之,会有更多功能来辅助函数式编程,并为每种语言创建更好的工具。
面临的最大挑战在于发布上述提到的有质量保证、可支持的软件需要耗费的大量工作。
Phil Haack:C#正朝着一个伟大的方向发展。目前其设计在 GitHub 上开放,社区可以跟进并为其发展做出贡献。它添加了很多灵感来源于函数式编程的功能,这让写代码变得更加愉悦。F#仍然是奇妙的函数式语言,它为 C#很多功能激发了灵感,但似乎很难跻身主流语言行列。
.NET 正在努力成长为跨平台开发的强劲选择,但在保持相对性和增长方面仍然面临着挑战。虽然 C#开发人员非常紧缺,但在学校、bootcamps 和 code academies 中教 C#的比例与 Node 和 JavaScript 相比少了太多。虽然.NET 生态系统很强大且在不断增长,但它还是非常依赖于 Microsoft。很少有大的公司为其 OSS 项目做出贡献。NPM 包数远多于 NuGet。扩大独立的社区非常重要。
另一挑战是现在 Web 的通用语言是 JavaScript。因此,在成为跨平台语言方面,Node 和 JavaScript 有着巨大的吸引力,而 C#比较少见于构建 Web 应用程序。这也就解释了 Electron 这样的平台的吸引力,它可以让你把你已经拥有的许多 Web 开发技能带入到本地应用程序开发中来。因此 C#和 F#还需要做一些努力来超过其他的语言(JS 在前,C#在后)。
Miguel de Icaza:.NET 延续了它在第一次推出时就确定的一个传统。它是一款不断根据开发人员需求发展的框架,它一直拥有强大的互操作性并努力在实现生产力的同时确保性能。
今天,.NET 几乎可以在所有可用的平台上使用:从服务器、台式机到移动设备、游戏机、虚拟现实、增强现实环境、手表,甚至是像 Raspberri-Pi 等类似的小型嵌入式系统。
整个框架以一种最开放的方式开源了代码,这也增加了成为未来 Unix 系统的核心组件到业界制造的新型秘密设备的可能。
实现生产力并确保性能对我来说非常重要,因为我从 2000 年开始使用.NET,那时候计算机只有现如今计算机的一小部分功能,但是.NET 已经提供了高性能运行,可以帮助开发人员创造出健壮的软件。这是通过保证安全的编程环境,通过设计避免常见的编程错误实现的。
这种实现已经被证明非常有用。我们需要随身携带便携式电脑,尤其是对于游戏开发人员来说,便携的电脑非常重要。开发人员仍然希望在小部分时间内,在没有高端计算机等设备的情况下创造出健壮的软件。
至于挑战,这部分非常有趣,我想分享关于一开始概要中提到的框架的发展历程的例子。
就像我所说的,.NET 的一个文化优势是根据市场的需求不断调整框架。从需要在本地完成的任务(比如运行环境优化)到分布式级(更高级的框架)。
在过去的几年中,我们不得不缩小框架来适应性能不足的设备,我们创造了智能链接器,将更智能的代码生成并创造映射到新的硬件的 APIs 上。
这种趋势一直持续了下去。举个例子,过去一年的重点任务就是完善.NET,支持开发高性能服务器和客户端代码的新型用户。这需要引入新的类型、原语和堆栈中的编译器优化。另一方面,现在.NET 的开发人员可以使用 Microsoft 创造的技术(Orleans、ServiceFabric)或是社区创造的技术(MBrace)来创建分布式系统。
在互操作性领域我们一直在各个方面开展工作。我们正在努力让.NET 程序员可以更简单地利用其他框架和语言写的代码,简化了在其他语言中使用.NET 代码(我们已经支持第一类 C、C++、Java 和 Objective-C),并简化了利用 Azure AutoRest 等工具与其他服务进行网络通信的过程。
InfoQ:Roslyn 的出现是如何帮助.NET 和你们的语言(C#/ F# / VB .NET 酌情而定)的成长的?
Richard Lander:这是一个非常简单的问题,可能我的回答会涵盖一些其他方面的内容,提及运行环境。.NET 运行环境存放这些语言和 Roslyn,将其模型(大多是垃圾收集和类型安全的内存)展示给开发人员。所以,缺少的是 C++(其他同行忽略不计)。.NET 运行环境团队用 C++ 编写,Roslyn 就可以存在,你就可以使用 C#。他们真的非常宽容!
csc.exe(原来 Roslyn C#编译器)也是用 C++ 编写的,所以同样的情况也适用于那里。
事实证明,编写平台原生组件的开发人员更喜欢 C#。第一次这么听说是吗?他们正在积极地寻求用 C#完成更多工作,并将更多的代码库转换为 C#。这是过度简化,但你可以将 Roslyn 仅仅认为是用 C#重写 csc.exe 的一个项目。同时,用 C#重写运行环境组件也同样重要。由于有引导问题,用 C#重写运行环境组件需要付出很多努力,但它是值得的。
C#代码库和 C++ 相比有很多优势,原因如下:
- 它大大增加了可以参与到代码库贡献中来的开发人员的基数。
- 我们有非常优秀的 C#工具,可以让开发变得更为高效。
- 可以直接让.NET 库运行在其他芯片和操作系统上。这对于在像 Raspberry Pi 上开发.NET Core 这样的代码库是很好的。
- 更容易了解安全问题。
因此在我看来,最主要的事情就是将现有的 C++ 代码库转移到 C#上。它使我们变得更加高效,让更多.NET 开发人员可以更方便地了解和操作基础平台。
Philip Carter:Roslyn 对我们发展.NET 非常关键,它帮助我们 Microsoft 构建更好的工具,并为开发人员提供了一个新的平台在语义上深入理解其代码库,以构建新的一组工具。
从语言开发者的角度来看,Roslyn 的直接好处之一是现代化的架构,可以添加新的语言功能,比以前 C#和 Visual Basic 的编译器更为容易。Roslyn 还推出了 Roslyn Workspaces,这是一个跨平台编辑器抽象层。现在用于 Visual Studio 和 Visual Studio Code(通过 OmniSharp),可以更轻松地利用各种语言服务。此外,F# 4.1 将成为第一个使用 Roslyn Workspaces 和自己的语言服务的 F#版本,改进了大量 IDE 工具并引入了新的功能。我们可以将 F#视为市场上唯一一款有高质量、一流的 IDE 工具的函数式编程语言,它一定有助于.NET 的发展。Roslyn Workspaces 可以帮助我们为所有.NET 语言提供更好的语言特性。
Roslyn Analyzers 通过提供一组 APIs,让你为 C#和 VB 代码库构建一组自定义工具,促进.NET 的发展。第一个改进是让人们可以更容易地构建强大的静态分析工具,但是你可以进一步使用像语义 diff 工具或其他需要了解你代码语义结构的东西。先于 Roslyn 出现,但是它实际上只适用于常使用静态分析工具的人。有了 Roslyn Analyzers 之后,这方面的开发现在由任何.NET 开发人员完成。
Phil Haack:这有很大的影响。在 Roslyn 之前,实现代码分析器的想法仅限于少数深入了解深奥原理的人。它的出现可以大众化地提升编译器,也为参与语言设计的人们铺平了道路。一方面提出了新的语言功能,另一方面也可以让其他人尝试它,并听取他们的想法。
Miguel de Icaza:它帮助统一了我们所有支持的平台上的 C#使用体验:Visual Studio、VSCode 和 Xamarin Studio,还有新的开发技术,可以轻松地编写活动代码,并在 iPad 上使用 Xamarin Workbooks 或是 Continuous 尝试活动代码。
关于工具,开发人员不得不依靠未成熟创建的语言或是黑客。在 C#世界中不必再这样做,因为我们现在有了新的方法,开发人员可以完全掌握 C#程序,操纵它并用完全相同的方式探索其语言世界。
F#较为独立,它结合了.NET 世界和函数式编程。这是一种总能引领潮流并非常适用于数据处理的语言。在这个对于机器学习兴趣异常高涨的时候,F#正是解决问题的良方。
InfoQ:开发人员要如何用官方的.NET 平台、.NET Core 平台和 Mono stacks?有办法“跟上”吗?什么应该用于新项目呢?
Richard Lander:2017 年我们的主要目标是减少你需要跟上的事情的数量。最初,我们的设计是希望.NET Core 与其他的.NET 平台能有显著的不同。后来,我们就推翻了这些决定,在 Visual Studio 2017 版本中让.NET Core 与其他的.NET 更为相似,在该版本中你会发现.NET Core 和.NET
Framework 以及 Xamarin 一样,转为使用 msbuild 构建引擎。这样的改变能帮助.NET mobile 和 Web 项目协同工作的体验变得更加简单。我们还标准化了所有.NET 平台都有的最小 APIs 集,称之为“.NET Standard”。我们将在 2017 年推出.NET Standard 2.0,并提供它的各种实现。这是我们曾定义且发布过的最大一组常用 APIs。它比最大的 Portable Class Library profile 还要大两倍。一旦.NET Standard 2.0 在所有.NET 平台实现,很多事情会变得更容易。许多人都期待它的发布,这是改变游戏规则的标准。
Philip Carter:这个问题问得很好,特别是在我们这么多年以来搭建了这么多东西的情况下。这是我喜欢的框架方式:
.NET 是跨平台的开发栈。它有一个标准库,称为.NET Standard Library,其中包含了大量的 APIs。这个标准库由各种.NET 运行环境实现:.NET Framework、.NET Core 和 Xamarin-flavored Mono。
.NET Framework 就是现有的开发人员一直使用的.NET Framework。它实现了.NET Standard Library,就是说任何仅依赖于.NET Standard Library 的代码都可以在.NET Framework 上运行。它包含了其他 Windows 专用的 APIs,比如说用于 Windows 桌面开发的 APIs 如 Windows Forms 和 WPF。.NET Framework 针对构建 Windows 桌面应用程序进行了优化。
.NET Core 是针对服务器工作负载优化的新的跨平台运行环境。它实现了.NET Standard Library,就是说任何使用.NET Standard Library 的代码都可以在.NET Core 上运行。该运行环境适合新的 Web 开发栈 ASP.NET Core 使用。它是现代的、高效的并为处理大规模的服务器和云工作负载设计的。
Xamarin-flavored Mono 是 Xamarin 应用程序的运行环境。它实现了.NET Standard Library,就是说任何仅依赖于.NET Standard Library 的代码都可以在 Xamarin 应用程序上运行。它包含了其他 iOS、Android、Xamarin.Forms 和 Xamarin.Mac 使用的 APIs。它针对在 iOS 和 Android 上构建移动应用程序进行了优化。
此外,从即将发布的 Visual Studio 版本开始,运行环境中的工具和语言都将变得很常见。当你创建任何类型的.NET 项目时,你将使用新的,但是已经由.NET 开发人员使用过多年的兼容的项目系统。MSBuild 用于构建项目,这就是说现有的构建系统可以用于任何新的代码,任何.NET
Standard 或.NET Core 代码可以与现有的.NET Framework 代码一起使用。所有.NET 语言在每个运行环境中都会用相同的方式编译和运行。什么应该用于你的新项目呢?这取决于你的需求。Windows 桌面应用程序?请使用.NET
Framework,就像你之前一直做的一样。服务器或 Web 应用程序?请使用 ASP.NET Core,运行在.NET Core 上。移动应用程序?请使用 Xamarin。类库和 NuGet 包?请使用.NET Standard
Library。使用标准库对于在你的所有应用程序中共享代码非常重要。要想跟上的最好方法就是阅读官方的.NET 文档。官方的.NET 博客也有很多有关这些问题的帖子,但请注意,以前的帖子并不能准确描述最新的.NET 发展。
Phil Haack:我倾向于比较保守。对于我的业务依赖的生产项目,我将使用经过试验的、真正的官方.NET 平台。但对于我的下一个项目,我一定会使用.NET Core,它没有十多年向后兼容性的需求。
Miguel de Icaza:多亏有.NET Standard,特别是我们在.NET Standard 2.0 中交付的 APIs,开发人员不需要太多地考虑哪个运行环境来运行他们的应用程序。跟上.NET 的人可能有兴趣了解我们为某些特定用例优化的运行环境(例如说,为移动应用和游戏优化的 Mono),但是在极大多数程度上,开发人员只需要知道,无论他们有什么需求,我们都已经为他们满足了。
当谈论到选择运行环境的问题,选择方式应该是这样的:
- .NET Framework 是以 Windows 为中心的框架,为 Windows 开发人员提供最好的服务。如果你正在搭建 Windows 为中心的应用程序,请你选择它。
- .NET Core 是云优化引擎,它是跨平台的。它使用相同的高性能 JIT 编译器,但在所有支持的操作系统(Windows、Linux、macOS)上运行代码。它没有特定的 Windows
APIs,因为这有悖于跨平台的目标。- Mono 是用于移动应用和 Apple 平台(Android、iOS、watchOS、tvOS)的运行环境,用于游戏控制器和 Unix 桌面应用程序。
InfoQ:你喜欢其他语言的什么功能,并会考虑使用?(C#/ F# / VB .NET 酌情而定)
Richard Lander:我喜欢 JavaScript(以及其他类似 JavaScript 的语言)的一点是,你可以直接在文件中开始写代码,即使是一行代码也可以运行。没有什么复杂的流程,也没有具体的概念要(提前)学习,这很有价值。有一些 C#脚本解决方案也是这样的,但它们没有很好地集成。我们的一些语言功能也在朝这个方向努力,但还没有做得这么好。我想如果能有个单行 C#文件,作为"Hello World" Web API,那就太棒了。
作为处理运行环境的人,我想把问题再次引回运行环境上。比如说我喜欢 JavaScript 和 PHP,因为它们可以从源代码快速读取并执行。我也喜欢 Go,因为它生成可执行的本地单个文件。.NET 是极少数的可以同时做到这两点的平台之一。我想看到我们为.NET 开发人员提供这两种选项,它们在真实场景中非常实用,特别是对于云编程来说这两个选项都很有帮助。
Philip Carter:我们最喜欢 C#和 Visual Basic 的功能之一就是不可空性。其中最大的,经常造成“十亿美元损失的错误”的问题就是空。如果没有在代码库中检查是否为空,那么每个.NET 开发人员都要努力寻找错误。可以将类型标记为非空就解决了问题,把空的问题从运行时问题转换为编译时问题。然而,要实现这一点是很大的挑战,因为目前 C#和 Visual Basic 的代码库没有不可空性。因此,这种功能可能需要选择性加入,并且不能破坏现有代码。这在 F#中实际上不算很大的问题,因为空性和不可空性已经是这个语言的功能了。然而,当与其他.NET 类型互操作时,F#开发人员还要关注空的问题。我们对选择性加入不可空性非常感兴趣。
我们感兴趣的另一组语言功能是能够实现更好的即时多态性,即协议 / 特性和类型种类。它们可以帮助你扩展现有类型的功能,尤其是更灵活的类型种类,可以帮助你定义某种行为,而无需将其“固定”到某种特定类型上。像任意类型的层次结构的语义等价比现在更为简单。虽然协议 / 特性和类型种类并不在我们的路线图中,但它们确实非常有趣,并帮助解决了你能碰到的有关.NET 语言的一些细微问题。
Miguel de Icaza:我不负责这些语言的发展,但是作为一个用户,我也希望 C#和 F#能包含这些功能。
对于 F#我的要求很简单:从个人来说,我非常依赖于它原来写循环的方式。我希望在循环中支持 break 和 continue。我知道这个要求有点奇怪,但这就是我最想要的功能:-)
对于 C#,我希望它能结合更多 F#好的想法,特别希望能引入 F#中的不可空性。
InfoQ:Microsoft 的开源调整已经进行了一年多了。它对于.NET 社区产生了什么影响或是改变?
Richard Lander:.NET 的开源调整从 2008 年发布 ASP.NET MVC 源代码就开始了,然后开源了 Web API 和 SignalR,到 2015 年开源完整的.NET Core。到现在为止,超过 50%.NET Core 的更改来自社区,C# repos 的数量每天也在 GitHub 上增长。和过去相比发生了翻天覆地的变化,并为未来绘制了锦绣的蓝图。
作为开源的维护者,我们在努力做着伟大的工作。我们在几个方面进行了突破:欢迎新加入的人,提供详细的 repo 文档和指导,设置 PRs 的高门槛,培养社区领导人并帮助运行项目。我们满足了社区的一些期望,并与社区进行对话,协商他们期望能与众不同的功能。从总体上来说,我觉得社区对于过去几年中.NET Core 和其他相关开源项目的发展情况是满意的(在很多情况下是相当满意的)。
.NET 生态系统积极健康的开源平台项目是非常有利的,它鼓励更多的人参与到更多的开源项目中来。实际上,它创造的价值是你多年以前难以定论的,但你现在可以非常确定地说.NET 是一个开源的生态系统。来自社区、小型企业、大型企业和公众的反馈非常积极。
Philip Carter:我认为向开源的转变给.NET 社区带来了巨大的好处。现在.NET 社区仍然热衷于开源,也可能会因为突然的过渡而产生波动,但人们已经看到了其中的价值和贡献。即使是在不常与开源开发相关的文档中,我们也看到了全社区参与进来做出的贡献,我们有近 100 名非 Microsoft 的贡献者。一名社区成员甚至评审了 Microsoft 员工在我们自己的存储库中做出的 pull 请求!我个人感觉.NET 社区已经具备了贡献于其开发堆栈的能力,这个发现让我非常激动。当然,这只是开始。当我们在 Visual Studio for .NET Standard 和.NET Core(这也是开源的)中发布质量工具的时候,期待会有更多.NET 开发者能关注进来,并为.NET 做出贡献。
Phil Haack:我可能算的不对,但这个活动已经进行了超过一年了。只是在过去一年中达到了最高峰。社区应该也注意到 Microsoft 想真正加入到开源社区的坚定决心,可能还需要一段时间才能达到目标。毕竟,MS 对开源的排斥远远超过一年,但我认为现在的态势是积极的。.NET 社区正在以一种前所未有的方式积极参与到.NET 未来的建设中。所有新的.NET Core 的开发和语言的设计都是在公共的 GitHub 上完成的,并接受大家的贡献,很高兴能看到这种态势。社区的人们参与度越来越高,而不仅仅是做一名配角进行客串表演。
Miguel de Icaza:这让开源.NET 社区和使用.NET 的人都感到非常激动。开源框架的好处在于框架是完全开放的,你就可以看到从性能,到内存使用,到提高精确度,到可扩展性等等方面对代码库的贡献。这是一种全面展示的良性循环,因为我们共同建设并培养.NET 社区。
结论
.NET 的开源已经成为了规划中的一部分,并预计将继续发展.NET Core 和.NET Standard 2.0。Microsoft 致力于发展跨平台,以吸引非 Windows 开发人员和平台实施者。
有关小组成员
Richard Lander是 Microsoft .NET 团队首席项目经理。他于 2000 年毕业于加拿大滑铁卢大学,获得英语荣誉学位,在计算机科学和 SGML/XML 标记语言领域进行了深入学习,后来直接在 Microsoft 工作。Richard 参与了.NET 各个方面的工作(他于 2003 年加入团队),包括与 Windows 集成,.NET 应用程序模型以及客户沟通。现在,Richard 主要参与.NET Core 开源项目,ASP.NET 5 的跨平台.NET 以及与其他.NET 公司 (Xamarin、Unity) 的合作。Richard 经常在.NET 博客和 @dotnet 推特账号上发表文章。在业余时间,他喜欢游泳、骑自行车和跑步,并且每年多次参与地方赛。他喜欢 80 年代英国摇滚和 Doctor Who。他在加拿大和新西兰长大。
Phillip Carter是 Microsoft .NET 团队项目经理。他目前主要做 F#工具、.NET 和.NET 文档。在加入 Microsoft 之前,Phillip 是俄勒冈州立大学的学生,他从事学生开发者导师的工作,并且是移动应用程序开发俱乐部的主席。
Phil Haack是 GitHub 负责客户端应用程序的工程总监,这个组包括桌面、基元、电子、编辑器工具团队。Haack 于 2011 年加入 GitHub,是.NET 社区的杰出成员。在加入 GitHub 之前,Phil 是 Microsoft 的程序经理。他的团队开发 NuGet 和 ASP.NET 。
Miguel de Icaza是 Microsoft 杰出工程师,他的团队负责创建令人愉悦的开发工具。他与 Nat Friedman 共同在 1999 年创建了 Ximian,并在 2011 年创建了 Xamarin。在此之前,Miguel 于 1997 年共同创建了 GNOME 项目,并自 2001 年创立以来一直负责 Mono 项目,包括 Novell 的多个 Mono 版本。Miguel 于 1999 年获得了免费软件基金会发布的免费软件奖,以及 MIT 技术评审创新者奖,并在 2000 年 9 月被提名为时代杂志评选的 100 名新世纪的创新者之一。
评论