Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions _blogposts/2020-09-23-release-8-3.md.raw
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
author: hongbo
date: "2020-09-23"
previewImg:
category: compiler
title: What's new in ReScript 8.3 (Part 1)
description: |
---


# What's new in ReScript 8.3 (Part 1)

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

ReScript@8.3 is available, people can try it via

```
npm i bs-platform@8.3.0
```

The changes are listed [here](https://github.com/rescript-lang/rescript-compiler/blob/master/Changes.md#83), 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


```ocaml
external readFileAsUtf8Sync : string -> (_[@bs.as "utf8"]) -> string = "readFileSync" [@@bs.val] [@@bs.module "fs"]
```

It can now be simplified as
```ocaml
external readFileAsUtf8Sync : string -> (_[@as "utf8"]) -> string = "readFileSync"
[@@val] [@@module "fs"]
```

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:

```ocaml
external input : string -> string = "default" [@@module "hello"]

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](https://github.com/rescript-lang/rescript-compiler/issues/4624),
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:

```ocaml
module N = struct
type t = {
x : int
}
end

let f (u : N.t) =
let {x } = u in 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!
177 changes: 177 additions & 0 deletions _blogposts/2020-09-23-release-8-3.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
---
author: hongbo
date: "2020-09-23"
previewImg:
category: compiler
title: What's new in ReScript 8.3 (Part 1)
description: |
---


# What's new in ReScript 8.3 (Part 1)

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

ReScript@8.3 is available, people can try it via

```
npm i bs-platform@8.3.0
```

The changes are listed [here](https://github.com/rescript-lang/rescript-compiler/blob/master/Changes.md#83), 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


<CodeTab labels={["ReScript", "Reason", "ML"]}>
```res
@bs.val @bs.module("fs")
external readFileAsUtf8Sync: (string, @bs.as("utf8") _) => string = "readFileSync"
```
```reason
[@bs.val] [@bs.module "fs"]
external readFileAsUtf8Sync: (string, [@bs.as "utf8"] _) => string =
"readFileSync";
```
```ocaml
external readFileAsUtf8Sync : string -> (_[@bs.as "utf8"]) -> string = "readFileSync" [@@bs.val] [@@bs.module "fs"]
```
</CodeTab>

It can now be simplified as
<CodeTab labels={["ReScript", "Reason", "ML"]}>
```res
@val @module("fs") external readFileAsUtf8Sync: (string, @as("utf8") _) => string = "readFileSync"
```
```reason
[@val] [@module "fs"]
external readFileAsUtf8Sync: (string, [@as "utf8"] _) => string =
"readFileSync";
```
```ocaml
external readFileAsUtf8Sync : string -> (_[@as "utf8"]) -> string = "readFileSync"
[@@val] [@@module "fs"]
```
</CodeTab>

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:

<CodeTab labels={["ReScript", "Reason", "ML"]}>
```res
@module("hello") external input: string => string = "default"

let a = input("hello")
```
```reason
[@module "hello"] external input: string => string = "default";

let a = input("hello");
```
```ocaml
external input : string -> string = "default" [@@module "hello"]

let a = input "hello"
```
</CodeTab>

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](https://github.com/rescript-lang/rescript-compiler/issues/4624),
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:

<CodeTab labels={["ReScript", "Reason", "ML"]}>
```res
module N = {
type t = {x: int}
}

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

let f = (u: N.t) => {
let {x} = u;
x + 1;
}; /* type error */
```
```ocaml
module N = struct
type t = {
x : int
}
end

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

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!