Sep 25, 2020

What's new in ReScript 8.3 (Part 1)

Hongbo Zhang
Compiler & Build System

Introduction

ReScript is a soundly typed language with an optimizing compiler focused on the JS platform. It's focused on type safety, performance and JS interop. It used to be called BuckleScript.

ReScript@8.3 is now available for testing, you can try it via

npm i bs-platform@8.3.0

The changes are listed here, this is a large release, and we will go through some highlighted changes.

Lightweight FFI attributes without bs. prefix

In this release, we make the bs. prefix optional, this will make the FFI less verbose.

For example, the old externals for readFileAsUtf8Sync used to be written like this

ReScriptReason (Old Syntax)ML Syntax
@bs.val @bs.module("fs")
external readFileAsUtf8Sync: (string, @bs.as("utf8") _) => string = "readFileSync"

It can now be simplified as

ReScriptReason (Old Syntax)ML Syntax
@val @module("fs") external readFileAsUtf8Sync: (string, @as("utf8") _) => string = "readFileSync"

Note almost all previous attributes with bs.xx can be simplified as xx with the exception of the following two that don't have abbreviations:

  • bs.send.pipe : this attribute was deprecated in favor of bs.send; you can still use the existing one for backward compatibility.

  • bs.splice : this attribute was deprecated in favor of bs.variadic; you can still use the existing one for backward compatibility.

default import in Es6 support

If you use es6 module output, the default bindings will be compiled properly now:

ReScriptReason (Old Syntax)ML Syntax
@module("hello") external input: string => string = "default"

let a = input("hello")

Will now be compiled properly under es6 format as below:

JS
import Hello from "hello"; var a = Hello("hello");

Customized js file extension support

Now user can pick up their js file extension support per module format:

JSON
"package-specs": [{ "module": "es6", "suffix": ".mjs" },{ "module": "commonjs", "suffix": ".cjs" }],

More flexible filename support

To have better integration with other JS infrastructures, for example, Next.js/React Native, we allow file names like 404.res, Button.Android.res so that it can just be picked up by those tools

Better type based inference for pattern let {a,b,c} = value

Previously, for code like this:

ReScriptReason (Old Syntax)ML Syntax
module N = {
  type t = {x: int}
}

let f = (u: N.t) => {
  let {x} = u
  x + 1
} /* type error */

You will get a type error

Error: Unbound record field x

However, since the compiler already knows the type of u, it is capable of looking up the label x properly. In this release, we make the original code style work out of the box without a work-around such as adding a module prefix like let {N.x} = ..

Build system enhancement

A lot of work is put in improving the build system, we will expand on this topic in the next post!

Happy Hacking!

Want to read more?
Back to Overview