js 装饰器_Reason & BuckleScript 发布了更接近 JS 的新语法!

405ddcd92909cb42cf518a0a81c1a3d0.png
好吧,刚说了没时间,结果这个新闻让我不得不抽出时间来写几句。

更新:BuckleScript 已经带着新语法改名为 ReScript,详情见问题:

如何评价 BuckleScript 带着新语法改名 ReScript?​www.zhihu.com

太长不看:题图就是新的「语法选项」!

6437244f671e02d1bc5f1cbcaa9f25b3.png
New Syntax for Reason & BuckleScript | Reason Blog​reasonml.org
828bfede6a47fa0cd94c622bd66e2395.png

注意,因为变化比较大,目前是作为「选项」(opt-in) 发布得。

所以长什么样?

我把题图的内容复制成代码过来:

if hasEaten {
  Js.log("more dessert please")
} else {
  Js.log("dessert please")
}

let message = j`Hello ${userName->Js.String.toUpperCase}!`

type student<'extraInfo> = {
  name: string,
  age: int,
  otherInfo: 'extraInfo,
}

@bs.val external window: {..} = "window"

window["addEventListener"]("focus", onFocus)

这尴尬的高亮……要不您还是看题图?

哎呀总之,有没有觉得像 JavaScript 以及其他 C-family 风格了许多?(那个长得像 C/C++ 的箭头并不是这次才有的,如果有兴趣可以搜一下 First pipe)。

我简单概括一下主要的改动:

一、终于可以完全 不 写 分 号 了!

其实以前的 Reason 语法在 95% 场合都是可以不写的,但是就是因为一些 edge cases 所以 Refmt(Reason 的格式化工具,大家都在用的 Prettier 就是借鉴自这个) 会给你加回来……现在终于可以完全扔掉分号了。

二、 泛型语法从 option(int) 变成了 option<int>

准确的术语是「参数化多态」,类型变量在定义是仍然需要 ML 风格的 ' 前缀,不过应用的时候跟 Flow/TypeScript 等等大家熟悉的 C 风格更接近了。

三、操作 JS 对象的语法就像 JS 一样……

Reason & BuckleScript 在与 JS 对象「互操作」的时候通常用 OCaml 的对象语义来表示 JS 的对象[1],但是以前的 Reason 语法(尽管已经比 OCaml 要更接近 JS 了)比较谜:

type person = Js.t({.
  name: string,
  desc: string,
});
// 表示 hux 是一个外来的,由其他 JS 提供为 jsHux 的对象,标注类型为 person 
[@bs.val] external hux : person = "jsHux";

let name = hux##name; // 读
hux##desc #= "NPC";  // 写

那么新语法呢……you ready?

type person = {
  "name": string,
  "desc": string,
};
@bs.val external hux: person = "jsHux" 
 
let name = hux["name"]
hux["desc"] = "NPC"

当当当当!是不是非常迷幻,乍一看都分不出这是哪个语言了?

四、更 JS 的字符串插值和异常捕获

// before
let str = {j|hello ${name}|j} 
try (foo) { 
 | Bar => 1
}

// after
let str = j`hello ${name}`
try foo catch { 
  | Bar => 1
}

五、数据容器字面量的调整

以前的 Reason 继承了 FP 语言列表(单链表)优先的做法,[1,2,3] 表示列表,数组需要表示为 [|1,2,3|]

新的语法则把 [1,2,3] 让给了在 JS 中更常用的数组,列表则表示为 list{1,2,3},这样的好处是以后可以把容器都表示为统一的风格,比如 set{...}map{...},而不用引入新的字面量。

六、这个长得像装饰器的东西长得更像 JS 装饰器了

恩,就是你看到的那个用于定义 BuckleScript 与 JS 互操作(FFI)的东西。 Reason React 定义组件也是用的这个:

[@react.component]
let make = (~name) => <button> {React.string("Hello!")} </button>;

// 现在可以省去方括号
@react.component
let make = (~name) => <button> {React.string("Hello!")} </button>;

在有参数的时候变化更明显:

  • [@foo bar] 变成了 @foo(bar)
  • [%foo bar] 变成了 %foo(bar)

这东西实际是 OCaml 的 extension attribute 和 extension node,不过在大部分场合你就当做 decorator 就好了。

七、其他变化还包括

  • if , switch , try 括号可选(这很 swift)
  • polymorphic variant(这东西你叫我怎么翻译?多态变体?)从 `foo 变成了 #foo

还有一些我就不翻译了,大家有兴趣的可以看这里有详细的语法变化介绍以及与 JS 语法对比的表格:

Reason Documentation​reasonml.org
f8b7f9f2dc761e48b237d8a9d8834f7b.png

虽然很多时候大家都爱说「语法是一个编程语言最不重要的东西」,但是 Reason 恰恰就是一个主要关于语法以及 JS 生态的项目。我个人是从知道这个项目开始就很兴奋 Reason & BuckleScript 团队能选定「往 JS 多靠点」的方向。有了抽象与封装的方向之后 FFI 不好用以及 leaky abstraction 就都能看到解决的路径了。

对我对 Reason 之前的一些想法有兴趣的同学可以看下面这个老回答:

Reason, ClojureScript, AssemblyScript 你更看好哪门语言的未来?​www.zhihu.com

最后,祝贺团队能够 launch 新语法!值得一提的是这次的 parser 重写主要是由非 Facebook 员工,开源社区的核心成员 Maxim(链接为推特)贡献的。之前说能不能把 Cheng Lou 拉到知乎来说几句话估计是要食言了…… @张宏波 要不要试试?

参考

  1. ^https://bucklescript.github.io/docs/en/object-2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值