Dark的新后端将在F#(2020)

2020-11-03 22:51:22

到目前为止,我的生活中还没有任何东西让我做好准备,因为我会故意选择迁移到.NET,但现在已经是2020年了,什么都不重要了。

在过去的两个月左右的时间里,我一直在为Dark Backend评估新的语言。由于一系列原因,OCaml的表现有点不令人满意。

在过去的几年里,我们总是说,当我们重写后端时,我们将在某个时候重写,这将会消失,等等。有很多新的代码需要在后端编写,以满足我们的路线图。我们真的要写一次,然后再重写吗?或者现在直接移植,然后在新堆栈中编写新代码会更快吗?

最终,我决定,如果要做出改变,现在就是时候。更重要的是,如果不会有什么变化,那么现在是完全致力于OCaml的绝佳时机,而不是第二次猜测这个选择。

起初,我希望去“铁锈”。Rust有很好的工具,很棒的库,一个令人愉快的社区,等等。但是在上面花了大约一个月的时间,我不能说我喜欢写Rust。尤其是,我不喜欢用Rust编写异步代码。我喜欢一种很好的高级语言,当你有一个像Dark这样大的项目要构建时,这就是你需要的。而铁锈不是那样的。接下来,我将发表“黑暗为何没有选择生锈”一书。或者我可以称之为“垃圾收集器”,你永远不会相信垃圾收集器为你做了多少事,因为这就是总结。

当我之前从事异步基准测试时,我真正做的是评估这些OCaml替代品中有没有更好的?如果是这样的话,它们也更快吗?我进行了评估,预计不会喜欢F#。我其实挺喜欢的。它与OCaml足够接近,有很好的库支持,而且到目前为止工具也是好的和糟糕的混合在一起。90年代的微软工具仍然在那里,这个比特并不是那么好,但总的来说,它比OCaml或Rust要好得多。

让我们从显而易见的开始,F#是OCaml。它是由世界上最大和最有经验的编程语言创建者支持的OCaml。在OCaml很棒的领域,F#也很棒!SUM类型、静态类型、急切执行、管道、不可变值,所有这些都非常棒。

在我看来,它实际上有一个更好的类型系统。突出的一点是,OCaml使地图的使用变得非常麻烦。比如哈希表,关联数组,随便你怎么称呼它们。看起来老版的真实世界OCaml已经被撤下了,所以我不能向你展示他们一开始有多令人不快。现在,在最新版本中,它们使用起来更加不舒服。而在F#中,你有一个Map<;OneType,AnotherType>;,这就是真正的地图<;OneType和AnotherType>;。魔法!

当然,我选择.NET的主要原因是库。它什么都有图书馆,真令人惊讶。虽然没有那么多的F#第一方库,但是每个供应商都有一个.NETSDK,您可以直接从F#使用。我期待着最终获得对Honeycomb、Rolbar和Google Cloud的第一方支持。多年来我一直告诉伊迪丝我会的,现在我甚至终于可以使用LaunchDarry了。

我真正喜欢的另一件事是文档和社区内容有多好。很多OCaml社区内容都是关于这门语言的,以及你能用它做些什么。F#开发人员似乎只想把狗屎做完。有数以百万计的博客帖子、YouTube视频等等,来自企业软件开发人员,他们在讨论构建Web软件的最佳方式。当然,还有非常详细和有用的FSharpForAndProfit,以及托马斯·彼得里克的作品-它真的很棒。

我认为这主要是因为社区的规模。我听人说过F#开发人员很少,大约有100万C#用户、10万VB用户和10K F#用户,或者类似的东西。我不确定到底什么才算用户,但我可以想象,在这个指标中,OCaml的用户不到100人,所以感觉我正在向一个庞大的社区进军。

不过,并不是每件事都令人惊叹。这套建筑系统很不美观。虽然paket与esy大致相当,但msbuild比沙丘差1000倍。在沙丘中的增量构建对我来说就像1,在.NET中就像6,即使什么都没有发生。我知道他们有漂亮的.NET增量式编译器,所以这让我感到困惑;如果有人有关于用F#进行真正快速编译的提示,我将不胜感激。

需要检查的一件重要事情是我是否可以将代码编译成JS。Dark的执行引擎也可以在编辑器中运行它,这是Dark与众不同的核心特性之一。正因为如此,我想采用未经更改的后端代码,并将其直接编译为JS。这不像Rescript(它是OCaml编译成的JS,语义和生态系统略有不同,或者是F#中的等价物,寓言)。幸运的是,F#代码可以使用Blazor编译成Wasm。Blazor将.NET运行时编译成WASM,并在其中运行您的代码。它也几乎不需要任何代码就能运行(尽管找出正确的咒语并不是一件容易的事)。

昨天的帖子吸引了很多人发表意见。除了一些Scala和Erlang的喜爱之外,很多人还提到了F#:

所以…我认为在这里做一个不错的选择是从OCaml切换到F#。你会得到几乎所有的好处,而大部分缺点都会消失。在大多数情况下,您可以直接将代码从OCaml转换为F#。-黑暗圣徒。

我已经在生产中的GCP上使用F#3年了,它非常棒,而且只会变得更好。您可以利用现有的.NET库(例如,您可以从Google获得官方的GCP库),如果您足够多地使用它们,就可以很容易地为它们编写一个函数包装器。-血管造影

我们考虑过OCaml,但选择了F#。我高兴得不能再高兴了。很棒的库,很好的工具,在2020年,多亏了C#和.NET Core,F#成为了云中的头等公民。您可以在Linux、Windows、MacOS上进行开发,无需修改即可运行。编译时间很长。除非您想要处理Rust中的低级特性和C++影响,否则F#是从OCaml迁移到更符合逻辑的步骤。还有适用于REPL的DotNet FSI。F#可以访问C#库,并且编写将NULL转换为None的薄包装器相对容易,因此您是NULL安全的或C#样式函数到ML样式函数,这样您就可以使用|>;或<;|etc.-l1x。

我最近将第一个F#代码合并到代码库中。它是Dark解释器核心的异步版本,连接到长颈鹿(F#39;与.NET的Kestrel Web服务器的低级接口)。

我的计划是重新实现相同的语言,但需要学习路线图中的一些内容。例如:

INT将是无限精确的(从技术上讲,这是一个突破性的变化,但不是AFAICT的重大变化)。

我将致力于使其等同于现有的Dark解释器,保持语义不变。在那之后,我将从“黑暗路线图”中制作新的功能。

Dark的后台是37K行的OCaml,其中8K行是测试,10K行是Dark标准库。所以到港口大约有两万条线路。应该会很有趣的。我的实施计划是实现平价-在此之后还有足够的时间来利用生态系统:

创建一个OCaml库来反序列化DB中的二进制操作码,并将它们转换为F#(我假设是通过JSON中介)。这将允许(可选的)将传入请求路由到F#服务。

添加模糊器以确保OCaml和F#版本的Dark的语义相同(尤其是库函数)

开始使用新设计记录痕迹(信不信由你,这实际上是推动整个更改的主要原因!)。

有很多事情要做,欢迎黑暗贡献者参加。移植标准库函数可能是一个简单的入门之处,添加语言功能也是如此。除了上面提到的以外,大多数东西都是直接来自OCaml的端口。和往常一样,如果你有任何问题,请随时在“空档”或“问题”中提问。

你可以在这里报名参加“黑暗”。欲了解更多关于Dark的信息,请关注我们的RSS,在Twitter上关注我们(或我),加入我们的松弛社区,或观看我们的GitHub回购。