最近体验了一下 Facebook 推的 ReasonML
说说我的感想(其实也不是最近,只是最近整理东西的时候翻到了以前尝试的时候留下的代码,就整理了一下然后发出来
ReasonML
是基于 BuckleScript
的,而后者又是基于 OCaml
实现的编译到 JavaScript
的语言。Facebook 还推出了 ReasonReact
,似乎是作为 cutting-edge 的 react
存在,这里我们先无视掉。
语法部分就不多说了,官网都有介绍,熟悉 OCaml
语法的人甚至可以不用看。
我这里直接以用他实现的 toy lib 说一说和 JavaScript
密切相关的部分
https://github.com/Shuumatsu/promise-channel
(这只是作为一个初体验的报告,并没有深层次的内容,或许我使用的时候也搞错了什么,但是真的没办法,文档真的太烂了...
(下面用到的代码部分是伪代码
首先是 Promise
,BuckleScript
提供了一个 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
这就导致了同一份代码,在 JavaScript
和 ReasonML
侧调用的时候会有完全不同行为。
和 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 也用不到,就没管了。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.