最近体验了一下 Facebook 推的 `ReasonML` 说说我的感想

2019-07-08 23:41:30 +08:00
 Yuigahama

最近体验了一下 Facebook 推的 ReasonML 说说我的感想(其实也不是最近,只是最近整理东西的时候翻到了以前尝试的时候留下的代码,就整理了一下然后发出来

ReasonML 是基于 BuckleScript 的,而后者又是基于 OCaml 实现的编译到 JavaScript 的语言。Facebook 还推出了 ReasonReact,似乎是作为 cutting-edge 的 react 存在,这里我们先无视掉。

语法部分就不多说了,官网都有介绍,熟悉 OCaml语法的人甚至可以不用看。

我这里直接以用他实现的 toy lib 说一说和 JavaScript 密切相关的部分

https://github.com/Shuumatsu/promise-channel

(这只是作为一个初体验的报告,并没有深层次的内容,或许我使用的时候也搞错了什么,但是真的没办法,文档真的太烂了...

(下面用到的代码部分是伪代码


首先是 PromiseBuckleScript 提供了一个 Promise 的 binding, https://bucklescript.github.io/bucklescript/api/Js.Promise.html

ReasonML 中 chain promise 类似于 monad

Js.Promise.resolve (transformer item) |> Js.Promise.then_ (fun transformed -> ...)

感觉类似于return (transformer item) >>= \transformed -> ...

这里 transformer 是一个一般的函数,但是实际上转译出来的 JavaScript 代码 transformer 可以是一个返回 promise 的函数,比如 const transformer = x => Promise.resolve(x+1). 如果 transformer 是这种实现,Js.Promise.then_ (fun transformed -> ...) 中的 transformed 的类型会是 'a Js.Promise.t, 而其实对 JavaScript 来说类型还是 'a(比如 Promise.resolve(Promise.resolve(1)).then(console.log) 会打印 1 而不是打印 promise

这就导致了同一份代码,在 JavaScriptReasonML 侧调用的时候会有完全不同行为。


Golang 中的 channel 不同,我尝试给我的 channel 添加一个可选的 transform 的功能

chan := make(string to int)
chan <- "1"
x := <- chan 
// x will be 1

所以现在就有了两种 channel,带 transform 的和不带的。内部实现的时候如果我使用同一个函数去处理 put 操作,那这个 string to int 的 transformer 因为类型系统就不合法,只能是 int to int

(仅仅是多一步 transformer? transformer(item) : item 我实在是不想把这两种 channel 区别对待


然后是 Iterator 部分

为了模拟 Golang 中的 for range 语法,我需要实现 Iterator Protocol

for await (const item of chan) {
    if (item === 5) {
        break
    }
    console.log(item)
}

但是 Facebook 的官方文档完全没有提到这方面相关的内容,而且没有提供 Symbol 的绑定。 而且似乎在 ReasonML 中根本不能实现 generator function(虽然我也没有用 generator hhh..)。 最后我选择在 JavaScript 文件中实现 Iterator Protocol


总的来说 ReasonML 还是处于非常早期的阶段,文档非常少,并且依赖 OCaml 的相关知识(虽然官方的说辞是不需要,但是一上来就是 ocaml attributes,我觉得还是很容易一头雾水的。

不支持 async/await,只能使用 promise,官方的说辞是暂时没有,怎么实现还没定,反正会有的。

调用 JavaScript 代码部分的设计感觉是很好的处理了 JavaScript 类型系统和 OCaml 类型系统的矛盾,但是写起来还是很麻烦,估计还是需要官方提供大量的 binding。

然后是用 OCaml 的库的问题,貌似是可以的,而且似乎 ReasonML 也能够无缝的在 dune 项目中使用,但是文档中着墨实在太少,这次我尝试写的 toy lib 也用不到,就没管了。

1955 次点击
所在节点    分享发现
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/581165

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX