V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Yuigahama
V2EX  ›  分享发现

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

  •  
  •   Yuigahama · 2019-07-08 23:41:30 +08:00 · 1953 次点击
    这是一个创建于 1751 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近体验了一下 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 也用不到,就没管了。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   983 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:09 · PVG 05:09 · LAX 14:09 · JFK 17:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.