我喜欢编程语言。每种语言都有自己的特性。近来,我开始苦恼一个问题:假若开始自己的项目的话,我该用哪些语言。
很多优秀的编程语言
在阅读此文之前,须要先说明几件事情。似乎在工作中大部份的时侯我都用Java、JavaScript和Ruby来创建产品应用,但我仍然在学习新的语言和新的框架。我相信,语言和语言(或框架)特有的社区能给你带来新的思想,这种思想早晚会有好处:函数式编程可以给你带来许多面向对象的编程知识,而全职从事Rails应用可以给你许多测试的经验(假如你写测试的话)。但问题是,假如你想学会所有每种语言的优秀概念,这么最终会在各类优秀的功能中迷失方向。
另一个关键点是,我仍然在用控制台。我使用笔记本的绝大部分时间都是在用浏览器和控制台。没错,我编程用的是Vim。我喜欢没有空值的类型系统(我喜欢可选类型),这种类型系统很强悍。为此我不喜欢Java的类型系统,但我用过的最新版本只是Java6,所以很有可能现今的情况不一样了!Java的类型系统正是我尝试Ruby的缘由,由于Ruby社区总是在谈论她们与Java的区别。听起来如同是,假如我写Java代码,我实际上是在帮助编译器干活,而不是编译器帮我干活。
我想说的最后一件事就是我在寻找的语言可能并不是你在找寻的语言!这篇文章里我会介绍一些我在近来几个月在工作和个人项目中用过的语言。
Ruby
我很喜欢Ruby。Ruby是个十分强悍的描述性语言,有许多成熟的函数库(称为“宝石”——gem),它们能帮你快速构建应用。Rails早已十分成熟,特别容易使用。测试在社区的融入程度比任何其他语言都要深。Ruby是个纯粹的面向对象语言,所以不管你使用哪些函数库,大多数代码都有相同风格的API,即类的API。社区也很强悍,Ruby的开发者虽然会给已有的函数库贡献代码,而不是每次都编撰自己的函数库(例如广为留传的ActiveRecord和Sequel就是挺好的反例)。这些共识帮助人们扩充函数库,其中的反例之一就是RailsAdmin的gem。
在速率方面Ruby并不是最快的。布署一般很重,须要很长时间才会加载。使用Ruby很愉快,但在现实中,运行Rails应用须要好多时间和好多成本,非常是在Heroku、AWSECS等“无服务器”的容器平台上,由于它要占用许多显存、磁盘空间、流量和启动时间,而这种都要额外花钱。在本地运行Rails完全没问题,Bundler也挺好用,但有时侯它的“热重载”机制会出问题。
JavaScript
我也喜欢JavaScript。绝大多数后端工作都是在Web上,由于每位人都有浏览器,所以发布很容易。所以使用其他语言虽然是件很奇怪的事情:“能招一个人为何要招两个?”JavaScript也很容易学习,但是由于它留传甚广、易于上手,所以使用JavaScript基本不会有错。使用这个简单的语言实现原型十分容易linux应用程序开发(java版),你可以直接启动node命令行环境,或则直接打开devtools!它们特别好用,任何开发web的人晓得它们,所以你有好多开发者!太好了。
为啥这是我们Wix使用的主要语言。
然而linux系统编程,JS也有问题。npm模块的状态与JS的状态不一样,在类型系统方面社区有分歧(Flowvs.TS),函数库和其他东西也是。我也有自己的喜好,所以……我认为我也是社区的一部份。这些缺少“社区精选”的结果就是即使npm上有好多模块,但好多模块都不成熟。我几年前写过一篇文章,述说的是我在完全使用JavaScript几年后又转到Ruby的故事。我称之为“倒退”。
Swift
近来我开始学习Swift进行iOS开发。之前我对它的了解为零,由于我了解的一切都只是如何创建React应用。即使这没哪些问题,但我想尝试些新东西。
Swift是个静态类型的编译语言。它最初被用于Apple生态环境下的应用程序开发,但它是开源的,如今也可以拿来开发Linux上的可执行文件。我晓得的最多产的一名npm作者SindreSorhus说他想做更多Swift的工作。我完全理解他!Swift的快速启动时间和好用的编译过程可以保证运行时的错误越来越少。并且它没有NULL值,而且却有Optional类型。在throw之前必须明晰申明函数会throw的内容,但并不是像Java那样通过throws申明进行,而是有个特别巧妙地句型糖,如同是“try一下,假如万一失败还有optional”。模式匹配通过与Swift枚举类型的完美配合,显得十分强悍。它还有类型推论,即使在方法定义中不能使用,但我认为应当问题不大。真是个完美的语言!
但为何Swift不是我的最终选择?由于Swift只适宜在XCode中使用。一般我使用Vim,用别的编辑器会认为效率很低。我尝试过VSCode和Atom,但都不太好。其实,最终我会写一个SwiftCLI工具能帮我编撰编辑器插件来改善开发体验,但起码如今这个东西还不存在。Swift也没有静态编译,所以你必须设置好Swift能够使用命令行程序。对于Mac应拿来说这不是问题,但在Linux服务器上,我希望编译出的二补码文件能包含一切。
ReasonML
我很喜欢这个Facebook为OCaml做的崭新句型。整个工具链觉得很成熟、很优秀。OCaml的包管理器OPAM自带表情图标,让这个看起来很老的工具当然不是这么老。Merlin和OCaml/Reason语言服务器也十分优秀,并且能与Vim配合得挺好。它还有个完美工作的手动完成引擎(!)、跳转到定义、鼠标悬停类型定义和更多的功能。优秀的开发工具从编辑器中分离,对于一门语言来说这是十分好的。
Reason可以用BuckleScirpot编译成JS,因而可以将Reason/OCaml代码转换成高性能的JS代码。这特别好,由于这就相当于JS也有了类型系统linux应用程序开发(java版),你还可以享受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开始linux安全加固,这么我们以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的优点。我不确定我喜欢哪种,但我认为这种都是候选。我感觉我只须要等待,瞧瞧这种语言在未来几个月或几晚会弄成哪些样子。
你最喜欢那个语言?欢迎在下方留言分享你的看法。
原文:
作者:GalSchleziner,Wix的后端开发。