相比高人气的 Rust、Go,为何 Java、C 在工具层面进展缓慢?( 三 )


 
后来的虚拟化和容器化进一步拓宽了随处运行的道路,但 Java 确实是第一种支持这类随处运行工作流的主要编程语言 。
 
随处运行中的最强者:Zig 
Java 方法当然不是完美的,首先就是 JIT 代码的启动速度很慢,另外是无法轻松调用非 Java 编写的代码 。GraalVM 声称能够解决这些问题,但目前的主流趋势仍然是提前交叉编译 。只要不包含 C 或 libc 依赖项,Rust 和 Go 就都能轻松实现随处运行 。
 
但目前随处运行中的最强者似乎要数 Zig,它不仅能够轻松完成 Zig 程序的交叉编译,还能兼容由 Clang 或 GCC 构建的任何代码 。
 
工具包管理器 
有语言就有编译器,其中提供大量标记可用于灵活调用,但使用过程也是相当麻烦 。所以出现了 Make 和 AUtotools 这类工具 。而后来的第三方工具包生态系统,又让复杂度提升了一个量级 。为了解决问题,出现了 Maven 和 pip 。但与之对应,我们又遇上了编译器或运行时版本不统一的问题,于是不同的程序就需要匹配不同的工具包版本 。Python 给出了自己的解决方案,就是 pipenv、妙手 ualenv 以及 conda 之类我压根理解不了的东西 。
 
所有这一切让复杂度继续提升,导致新用户几乎跟不上节奏 。因此,新的语言开始尝试把这些一切集中管理起来,简化开发流程 。
 

我想说,工具包管理和 LSP 是我编程职业生涯中见证过的,真正改变游戏规则的两大重要因素 。
——Ganesh Sittampalam
 
就像内置“电池”标准库扩展了语言的定义一样,现代工具包管理器也大大提高了开发者对于体验的预期 。这种扩展的优势在于易上手、开发体验更好,缺点就是软件的打包、发布和构建会带来相应成本 。语言作者需要在工具中投入大量时间来解决这些问题 。
 
工具包管理器中的最强者 
我认为 cargo 的一大核心优势,在于它与语言相伴而生 。而以往的主动构建工具往往缺乏与整个平台的全面集成 。
——Robert Masen
 
工具包管理器正在迅速发展 。所以只要舍得投入工程时间,我们就能显著改善自己语言的上手和日常使用体验 。于是,新项目在这方面的投入与日俱增 。
 
Rust 的 cargo 和 rustup 文档在体量上已经基本看齐 rust book,而且就这还不足以涵盖所有 cargo 插件 。无论是轻松切换语言的编译器版本、快速运行测试、执行代码覆盖与性能测试、获取供应商代码、生成说明文档、校验代码还是修复校验问题,这些以往存在于语言生态系统中的独立工具,如今都成为 Rust 中的开箱即用功能 。Go 的情况也差不多 。可以想见,后续出现的新语言要想百尺竿头更进一步,需要付出多少努力 。
 
代码格式化器 
代码格式化器早在 gofmt 之前就已经出现,就如同 CPAN 之前就已经出现了第三方工具包,但这一切的最终成熟需要等待一场颠覆社区标准的深刻变革 。
 
例如,在 Go 之前出现的任何语言,都不可能像 Go 那样实现几乎 100%的样式一致性 。这是因为之前的语言必须兼容原有代码,而 gofmt 则强制执行单一样式,且不提供任何调整选项 。Go 之后的语言当然也就站在巨人的肩膀上,于是 Rust(rustfmt)和 Zig(zig fmt)同样采用强大的默认代码风格与随附的代码格式化器,并由此建立起开发者体验优势 。
 
其实可以聊的还有很多,包括运行时改进,其基本相当于对语言的直接改进 。IDE、LSP、模糊支持和重构工具等,则把侧重点放在了开发者这一边 。但受篇幅所限,我们不可能无限延伸下去 。
 
也有一些在语言创造者眼中必将改变世界的成果,最终从未得到广泛采用,或者只在某个特定领域拥有影响力 。很明显,Jupyter notebook 与 REPL 就是典型 。它们在某些应用领域特别关键,但在其他领域却毫无知名度 。Smalltalk 基于图像的方法和 Mathematica/Wolfram 语言的语言集成数据虽然极具特色,但也更加小众 。
 
总结 
能帮助开发者顺利完成工作的工具,已经是编程语言可用性中的重要组成部分 。而工具本身也在持续变化,标准不断提高 。
 
整个过程基本就是:在出现新的开发者创新工具时,比较年轻的编程语言更有机会将成果融入自身生态系统,由此形成增量优势 。随着时间推移,这些增量优势会推动开发者体验迎来质变 。


推荐阅读