我喜欢编程语言。每种语言都有自己的特点。最近,我开始纠结一个问题:如果开始自己的项目的话,我该用什么语言。
好多优秀的编程语言
在阅读此文之前,需要先说明几件事情。虽然在工作中大部分的时候我都用 Java、JavaScript 和 Ruby 来创建产品应用,但我一直在学习新的语言和新的框架。我相信,语言和语言(或框架)特有的社区能给你带来新的思想,这些思想早晚会有用处:函数式编程可以给你带来许多面向对象的编程知识,而全职从事 Rails 应用可以给你许多测试的经验(如果你写测试的话)。但问题是,如果你想学会所有每种语言的优秀概念,那么最终会在各种优秀的功能中迷失方向。
另一个关键点是,我一直在用控制台。我使用电脑的绝大部分时间都是在用浏览器和控制台。没错,我编程用的是 Vim。我喜欢没有空值的类型系统(我喜欢可选类型),这种类型系统很强大。因此我不喜欢 Java 的类型系统,但我用过的最新版本只是 Java 6,所以很有可能现在的情况不一样了!Java 的类型系统正是我尝试 Ruby 的原因,因为 Ruby 社区总是在谈论他们与 Java 的区别。听上去就像是,如果我写 Java 代码,我实际上是在帮助编译器干活,而不是编译器帮我干活。
我想说的最后一件事就是我在寻觅的语言可能并不是你在寻找的语言!这篇文章里我会介绍一些我在最近几个月在工作和个人项目中用过的语言。
Ruby
我很喜欢 Ruby。Ruby 是个非常强大的描述性语言,有许多成熟的函数库(称为“宝石”——gem),它们能帮你快速建立应用。Rails 已经非常成熟,非常容易使用。测试在社区的融入程度比任何其他语言都要深。Ruby 是个纯粹的面向对象语言,所以不管你使用什么函数库,大多数代码都有相同风格的 API,即类的 API。社区也很强大,Ruby 的开发者似乎会给已有的函数库贡献代码,而不是每次都编写自己的函数库(比如广为流传的 ActiveRecord 和 Sequel 就是很好的例子)。这种共识帮助人们扩展函数库,其中的例子之一就是 Rails Admin 的 gem。
在速度方面 Ruby 并不是最快的。部署通常很重,需要很长时间才能加载。使用 Ruby 很愉快,但在现实中,运行 Rails 应用需要很多时间和很多成本,特别是在 Heroku、AWS ECS 等“无服务器”的容器平台上,因为它要占用许多内存、磁盘空间、流量和启动时间,而这些都要额外花钱。在本地运行 Rails 完全没问题,Bundler 也很好用,但有时候它的“热重载”机制会出问题。
JavaScript
我也喜欢 JavaScript。绝大多数前端工作都是在 Web 上,因为每个人都有浏览器,所以发布很容易。所以使用其他语言似乎是件很奇怪的事情:“能招一个人为什么要招两个?”JavaScript 也很容易学习,而且因为它流传甚广、易于上手,所以使用 JavaScript 基本不会有错。使用这个简单的语言实现原型非常容易,你可以直接启动 node 命令行环境,或者直接打开 devtools!它们非常好用,任何开发 web 的人知道它们,所以你有很多开发者!太好了。
难怪这是我们 Wix 使用的主要语言。
但是,JS 也有问题。npm 模块的状态与 JS 的状态不一样,在类型系统方面社区有分歧(Flow vs. TS),函数库和其他东西也是。我也有自己的喜好,所以……我觉得我也是社区的一部分。这种缺乏“社区精选”的结果就是虽然 npm 上有很多模块,但很多模块都不成熟。我几年前写过一篇文章,讲述的是我在完全使用 JavaScript 几年后又转回 Ruby 的故事。我称之为“倒退”。
Swift
最近我开始学习 Swift 进行 iOS 开发。之前我对它的了解为零,因为我了解的一切都只是怎样创建 React 应用。虽然这没什么问题,但我想尝试些新东西。
Swift 是个静态类型的编译语言。它最初被用于 Apple 生态环境下的应用程序开发,但它是开源的,现在也可以用来开发 Linux 上的可执行文件。我知道的最多产的一名 npm 作者 Sindre Sorhus 说他想做更多 Swift 的工作。我完全理解他!Swift 的快速启动时间和好用的编译过程可以保证运行时的错误越来越少。而且它没有 NULL 值,但是却有 Optional 类型。在 throw 之前必须明确声明函数会 throw 的内容,但并不是像 Java 那样通过 throws 声明进行,而是有个非常巧妙地语法糖,就像是“try 一下,如果万一失败还有 optional”。模式匹配通过与 Swift 枚举类型的完美配合,变得非常强大。它还有类型推断,虽然在方法定义中不能使用,但我觉得应该问题不大。真是个完美的语言!
但为什么 Swift 不是我的最终选择?因为 Swift 只适合在 XCode 中使用。通常我使用 Vim,用别的编辑器会觉得效率很低。我尝试过 VSCode 和 Atom,但都不太好。也许,最终我会写一个 Swift CLI 工具能帮我编写编辑器插件来改善开发体验,但至少现在这个东西还不存在。Swift 也没有静态编译,所以你必须设置好 Swift 才能使用命令行程序。对于 Mac 应用来说这不是问题,但在 Linux 服务器上,我希望编译出的二进制文件能包含一切。
ReasonML
我很喜欢这个 Facebook 为 OCaml 做的崭新语法。整个工具链感觉很成熟、很优秀。OCaml 的包管理器 OPAM 自带表情图标,让这个看上去很老的工具其实不是那么老。Merlin 和 OCaml/Reason 语言服务器也非常优秀,而且能与 Vim 配合得很好。它还有个完美工作的自动完成引擎(!)、跳转到定义、鼠标悬停类型定义和更多的功能。优秀的开发工具从编辑器中分离,对于一门语言来说这是非常好的。
Reason 可以用 BuckleScirpot 编译成 JS,因此可以将 Reason/OCaml 代码转换成高性能的 JS 代码。这非常好,因为这就相当于 JS 也有了类型系统,你还可以享受 JS 的函数库。我很喜欢它。实际上,我唯一不喜欢的就是我得建立大量的类型定义才能使用依赖,但通常这并不是问题:我们不需要对整个模块建模,只需要对输入、输出和使用到的特定函数、类和方法建模即可。因为 Reason 并不是完全的函数式(有副作用),因此在我看来, Reason 是最好的能编译成 JS 的语言。
Reason 也能编译成字节码或原生代码。使用纯 OCaml/Reason 意味着只要编译器通过,就不会有运行时的错误,它也能静态编译,生成很小的二进制文件,启动速度也很快。而且它编译速度非常快!
OCaml工具链非常快!
在尝试原生 Reason 应用时我遇到的最大问题就是我不知道别人在干什么,别人怎样使用函数库。大多数人都使用OCaml,但因为 OCaml 和 Reason 可以互换,所以我可以用 Chrome 扩展把 OCaml 当做 Reason 来阅读。但依然不清楚。一些 OCaml 代码不能转换成 Reason,也许是因为 Chrome 插件中缺乏 PPX。据我的理解,PPX 是一种语法扩展,基本上就是一些宏,将代码从一种语法转换成另一种语法。可以理解成 Babel 插件或类似的东西。原生的 Reason/OCaml 不支持多核心,但要想实现并发,可以使用 Lwt,这是个类似于 Promise 的库。但我还没找到哪怕一篇 Lwt 的指南或文章!
而且,似乎即使是原生 OCaml/Reason开发,入门的门槛也非常高,而且非常打击积极性。社区不会解答问题也不会分享知识,绝大多数情况下都是要求提问者去看源代码或借口,但我相信最终这会改变,因为这只是 JS 开发的开始。
Golang
Go 是个非常好的语言。它很容易学习,编译和运行都很快,还有 goroutine 和通过 CSP 实现的简单并发。它支持多核心,而且可以编译出静态二进制文件,能在最简洁的Linux上快速启动。它在变量定义时有类型推断,但函数定义中没有。它支持接口,看上去像是来自于有良好基础的专业社区。
实际上,有很多很强大的模块和应用都是用 Go 写成的,如 Docker、Kubernetes、CockroachDB,意味着你有可能将这些二进制文件作为基础设施的一部分,从而实现小型的、简单的分发(如在树莓派上)。这一点非常强大。
在公用数据结构(图、树等)和算法方面,它没有泛型(也许下个版本就会加上了),我觉得这一点很奇怪:你必须每次都编写同样的代码,或者使用代码生成,虽然也能用,但我更希望编译器能帮我完成这一切。而且,我并没有完全理解它的模块系统 VGO,但我猜测随着社区对之越来越熟悉,以后会有更多的信息和更简单的指南。最后一点个人意见,我认为语言本身不太干净。我知道,这并不是不使用某个语言的理由,但至少我不会完整地测试它,或者在个人项目中使用它。Go 语言本身并不有趣。它很简单,很无聊,很好。我相信最后我会在某个正式系统中使用并爱上它。人的口味会变化!
Crystal
这篇文章以 Ruby 开始,那么我们以 Crystal 结束吧。
Crystal 是另一门非常新的语言,它还没到 1.0 版本。看上去很像 Ruby,但它是编译语言,有静态类型,而且很快!它像 Ruby 一样支持 OOP,而且有很多很不错的功能,如类型推断、optinoal 类型、用于并发的 CSP 和编译时宏,有点像 Golang 的 codegen,但它的编译器本身就支持。Crystal 有几个新的 Web 框架,比如 Lucky 和 Amber。还有 Kemal,虽然它是 Sinatra 的,但也可以用在 Crystal 上。还有 ORM,而且由于 Crystal 重构了 Ruby(用 Elixir 做了些修饰),你会发现它的 ORM 的 API 与 Ruby 几乎相同,而且还有类型安全。这个非常重要!
由于这个语言还非常年轻,所以它还需要一段时间才能用于产品。我喜欢 Crystal 的并发,它能使用所有的核心,就像 Go 语言一样,但 Crystal 不需要手动去 fork。我还喜欢它抛出异常会返回 result 类型,这样错误处理可以明确进行了。我希望枚举能有自己的值,这样就能像 Swift 和 OCaml 一样使用了。更好的编辑器支持也是必要的,自动完成、鼠标悬停类型提示都非常有用。此外,使用 Scry 可以使语言服务器的自动完成用于标准库,但无法用于用户自己的代码。我还有点担心 Crystal 不会到达发布 1.0 的那一天,但我真心希望它能发布。
可能你也看出来了,我希望未来的编程语言能够吸取 Crystal、Go 和 ReasonML 的优点。我不确定我喜欢哪种,但我觉得这些都是候选。我觉得我只需要等待,看看这些语言在未来几个月或几年会变成什么样子。
你最喜欢哪个语言?欢迎在下方留言分享你的想法。喜欢小编轻轻点个关注哦!