来源:36氪
这篇文章,原标题是TheseModernProgrammingLanguagesWillMakeYouSuffer,作者IlyaSuzdalnitski在文章中针对15种编程语言展开了详细测评,希望对你有所帮助。
图片来源:saashub
懒人目录
概述篇:编程语言最重要的特征
一星篇:C++,JAVA
二星篇:C#,Python,Rust,TypeScript
三星篇(上):Go,JavaScript
三星篇(下):Haskell,OCaml,Scala
四星篇:Elm,F#
五星篇:ReasonML,Elixir
ReasonML
ReasonML是一门最终会被编译成JS语言的函数式语言,它主要应用在web前端开发中。ReasonML不是一门新语言,它是OCaml(一种古老而久经考验的编程语言)的新语法。ReasonML由Facebook提供支持。
通过利用JavaScript生态系统,ReasonML没有OCaml同样的缺点。
所属的编程语系:ML
不是JS的超集
ReasonML的语法和JS类似,这使得使用过JS的人很容易上手ReasonML。但是,不像TypeScript,ReasonML并不是JS的超集,也没有继承JS数十年来积累的一些糟糕设计。
学习时需要付出的代价
因为ReasonML不准备成为JS的超集,所以这门语言比JS简单很多。任何有过用JS进行函数式编程经验的人,都可以在差不多一周之内上手ReasonML。
ReasonML真的是这里提到的最简单的编程语言之一了。
函数式,但非纯函数
不像Elm,ReasonML甚至不准备成为一门纯的函数式语言,也没有“永不出错”的目标,这意味着ReasonML非常实用,并且专注于开发者生产力,能很快地实现结果。
类型系统
ReasonML就是OCaml,这意味着它的类型系统几乎和Haskell一样好,ReasonML类型系统最大的缺点是,缺乏类型类,不过它支持函子(更高阶的模型)。
ReasonML是静态类型的,它的类型推论几乎和Haskell一样好。
生态系统
不像TypeScript,ReasonML已经获取了整个JS生态系统。
JS/TypeScript互操作
ReasonML编译成纯JS,因此可以在同一个项目中同时使用ReasonML和JS/TypeScript。
ReasonML与React——绝配
如果你正在进行web前端开发,那么你就有机会使用React了。你是否了解,React最开始就是用OCaml写的,然后才被移到JS上来帮助采用?
因为ReasonML是静态类型的,所以无需担心PropType。
还记得JS测评部分那个看上去无害但是却导致了性能灾难的例子吗?
ReasonML对于不可变性数据结构有合适的支持,这样的代码不会造成性能问题:
id:“0”,
firstName:“John”,
}
friends=[samantha,liz,bobby]
onClick={id=Js.log(“clicked”++id)}
/
与JavaScript不同的是,当使用ReasonML时,没有任何东西会得到不必要的重新呈现,非常好的开箱即用的React性能。
工具
ReasonML几乎不像它的替代语言们那样成熟(比如TypeScript),它在工具方面有一些问题。举个例子,官方推荐的VSCode扩展推论语言服务器目前已损坏,不过还有其他替代品。
ReasonML在底层使用了OCaml编译器,而OCaml以非常糟糕的编译器错误消息而“臭名昭著”。虽然这不是致命的缺陷,但还是有点令人沮丧,并可能影响开发人员的生产力。
我希望随着这门语言变成熟,它的相关工具能够有所改进。
空值
ReasonML没有空引用,它用Option模块来表示可能不存在的值。
不可变性
ReasonML为不可变性数据结构提供了一流支持。
模式匹配
ReasonML有很好的模式匹配支持。
结论
ReasonML可能就是TypeScript想要实现的结果,只不过TypeScript失败了。ReasonML在JS的基础上增加了静态类型,同时删除了所有糟糕的特征(并增加了真正重要的现代特征)。
最佳前端语言奖
ReasonML获得了“最佳前端语言奖”。毫无疑问,ReasonML是web前端开发最好的选择。
Elixir
Elixir可能是世界上最受欢迎的函数式编程语言了。和ReasonML一样,Elixir并不是一门真正的新语言。Elixir是在Erlang三十多年的成功之上建立的。
Elixir是Go的函数式表亲。和Go相似,Elixir最开始就专注并发性来设计,这是为了利用多核处理器的优点。
和一些其他函数式语言不同的是,Elixir非常实用。Elixir专注于结果,我们不会在Elixir社区看到很多学术讨论,Elixir论坛上充满了实际问题的解决方案,这个社区对新手特别友好。
所属的编程语系:ML
生态系统
Elixir的闪光点在于它的生态系统。在大多数其他编程语言中,语言和生态系统,是两个独立的东西。而在Elixir中,生态系统中的核心框架是由核心Elixir团队开发的。
JoséValim是Elixir语言的设计者,也是Phoenix和Ecot——Elixir生态系统中两个超级酷的库——的主要贡献者。
在绝大多数其他语言中,有多个不同的库专注同一个任务——许多不同的web服务器,许多不同的ORM等等。在Elixir中,开发需要专注于一些核心的库,因此库的质量也非常高。
Elixir库的文档特别好,有许多例子。不像一些其他语言,Elixir的标准库也有很多相关文档。
Phoenix框架
Phoenix框架的口号是“Phoenix感觉刚刚好”。与其他语言中的框架不同,Phoenix有很多内置功能。它开箱即用,支持WebSocket、路由、HTML模板语言、国际化、JSON编码器/解码器、无缝ORM集成(Ecto)、会话、SPA工具箱等等。
Phoenix框架因强大的性能而出名,它能够在一台机器上处理数百万个同步连接。
全栈Elixir
Phoenix框架最近引入了LiveView,它允许在Elixir中建立丰富的实时web接口(对比单页应用程序)。不需要JS,也不需要React!
LiveView甚至可以负责同步客户端和服务器状态,这意味着我们不必为REST/GraphQLAPI的开发和维护操心。
数据处理
当处理很多和数据处理相关的任务时,Elixir是Python的可靠替代品。在用Python和Elixir构建了一个网页数据抓取工具之后,对比发现,Elixir对于这个任务,是一门更好的语言和生态系统。
像Broadway这样的工具允许在Elixir中构建数据摄入/数据处理管道。
类型系统
在我看来,缺少恰当的静态类型是Elixir最大的缺点。因为Elixir不是静态类型,它的编译器(以及dialyzer)会在编译时报出很多错误。这和动态类型语言(比如JS,Python,以及Clojure)有很大不同。
速度
Elixir编译器是多线程的,提供了极快的编译速度。与JVM不同,ErlangVM启动速度很快。对于Elixir的用例来说,运行时性能非常好。
可靠性
Elixir是在Erlang之上创建的,Erlang花费了超过三十年的时间来创建世界上最可靠的软件。一些在ErlangVM之上运行的程序能够实现99.%的可靠性。世界上没有其他的平台拥有同样水平的可靠性。
并发性
大多数其他编程语言都不是为并发性而设计的。这意味着,编写使用多线程/多处理器内核的代码远不是一件小事。
其他编程语言使用执行并行代码的线程(以及线程读/写入的共享内存)。这种方法通常容易出错,容易出现死锁,并导致复杂性呈指数级增长。
Elixir构建在Erlang之上,Erlang以其出色的并发特性而闻名,它采用了一种完全不同的并发方法,称为actor模型。
在这个模型中,进程(actor)之间没有共享的内容。每个进程都保持各自的内部状态,在不同进程之间通信的唯一方法是发送消息。
值得提及的是,正如它的创建者阿伦·凯(AlanKay)最初所设想的那样,actor模型实际上是OOP,它没有任何东西是共享的,而对象只通过传递消息进行通信。
让我们来快速对比Elixir和它命令式表亲Go:
和Go不同,Elixir起初是为了容错率而设计的。当一个goroutine崩溃时,整个Go程序都会崩溃。在Elixir中,当一个进程挂掉时,只有这一个进程会挂掉,而不会影响程序的其余部分。
更好的是,失败的进程会由主管自动进行重启。这允许失败的进程重试失败的操作。
Elixir进程也非常轻量,一个人可以轻松地在一台机器上执行成千上万个进程。
扩展
让我们再和Go作一个比较。Go和Elixir中的并发性都利用了并发进程之间的消息传递。因为Go编译为本机代码,所以Go程序在第一台机器上运行得更快。
但是,一旦你开始扩展到第一台机器之外,Go程序就会开始输掉比赛。为什么?因为Elixir从一开始的设计就是可以在多台机器上运行的。
Elixir运行的ErlangVM在分发和扩展方面非常出色。它可以无缝处理许多繁琐的事情,如集群、RPC功能和网络。
在某种意义上,在微型服务真正面世的数十年前,ErlangVM就已经实现了微型服务。每个进程都可以被理解为一个微型服务——和微型服务一样,每一个进程都是独立的。
在语言内置通信机制的情况下,进程在多个机器上运行是一件普遍的事情。
没有Kubernetes复杂度的微型服务?仔细了解一下,你就会理解Elixir设计的真正目的。
错误处理
Elixir用特殊的方法进行错误处理。纯函数式语言(Haskell/Elm)被设计出来是让错误的可能性最小化,而Elixir则假设错误一定会发生。
在Elixir中,允许抛出异常,但是捕获异常一般是不被鼓励的行为。进程主管会自动让程序一直运行。
学习时需要付出的代价
Elixir是一门简单的语言,新手可以花一到两个月入门。使学习变得困难的是OTP。
OTP是Elixir的杀手级特性。OTP是一套来自Erlang的工具和库,而Elixir是在Erlang基础之上建立的。这是一种“秘方”,它大大简化了并发和分布式程序的构建。
虽然Elixir本身很简单,但使用OTP设计Elixir系统会花上一点时间,至少对我来说是如此。
学习资源
作为最受欢迎的编程语言,Elixir有着丰富的学习资源。这些学习资源往往对新手也很友好。
模式匹配
Elixir有很好的模式匹配支持。
数字处理
Elixir不能很好地处理计算密集型任务。编译成本机语言的编程语言能够更好地处理这些任务(比如Go/Rust)。
那Erlang怎么样?
对于企图和目的,Elixir和Erlang的本质是相同的。Erlang是一种功能强大的语言,它的语法很奇怪。Elixir可以被认为是Erlang的一种更好、更现代的语法(还有非常好的生态系统和社区)。
结论
Elixir可能是所有函数式语言中最成熟的,它也可以在为函数式编程制作的虚拟机之上运行。Elixir最开始是针对并发性设计出来的,并且在多核处理器的现代社会中,它是最完美的搭配。
奖项
Elixir获得了两个奖项。
第一,它的弹性、函数优先的方法和惊人的生态系统使它成为“构建webAPI的最佳语言”。
第二,OTP和actor模型使得Elixir成为“构建并发和分布式程序的最佳语言”。和命令式表亲Go不同的是,用Elixir编写的软件能够横向扩展到成千上万个服务器上,并且有开箱即用的容错率。
写在最后:在工作中使用正确的工具
图片来源:HaupesCo。/Unsplash
你会用螺丝刀锤钉子吗?应该不会吧。那么,我们也不应该试图用一门编程语言完成所有任务,每一门语言都有它最合适的工作领域。
Go是最适合系统编程的语言。最适合前端开发的语言毫无疑问是ReasonML,它符合一门极好的编程语言的绝大部分要求。
WebAPI开发的冠军绝对是Elixir,它唯一的缺点就是缺少静态类型系统(这一缺点也因为其良好的生态系统、社区、可靠性,以及并发特征而抵消了)。对于任何类型的并发软件/分布式软件,最好的选择是Elixir。
如果你正在数据科学领域工作,那么,非常遗憾的是,你只能选择Python了。
文已至此,我衷心地希望,这篇文章能够对你有所帮助。比较编程语言并不是一件容易的事,不过我已经尽力了。