The compiler sometimes optimizes code, do we have it written down when/how it decides to do this?

Here’s an example:

// rescript
type cat = {name: string}

let my_cat = {
  name: "fluffy",
}

let cat_name = my_cat.name

Outputs:

// Generated by ReScript, PLEASE EDIT WITH CARE

var my_cat = {
  name: "fluffy"
};

var cat_name = "fluffy";

export {
  my_cat ,
  cat_name ,
}
/*  Not a pure module */

Instead of just transpiling from ReScript to JS, it’s improving the output since the compiler knows what the value of my_cat.name is.

It can also do this with function calls:

// rescript
type cat = {name: string}

let my_cat = {
  name: "fluffy",
}

let getName = cat => cat.name

let name = getName(my_cat)

Outputs:

// Generated by ReScript, PLEASE EDIT WITH CARE

function getName(cat) {
  return cat.name;
}

var name = "fluffy";

var my_cat = {
  name: "fluffy"
};

export {
  my_cat ,
  getName ,
  name ,
}
/* No side effect */

If I use an object instead of a record, it does not do the same to the output:

// rescript
let my_cat = {
  "name": "fluffy",
}

let getName = cat => cat["name"]

let name = getName(my_cat)

Outputs:

// Generated by ReScript, PLEASE EDIT WITH CARE

var my_cat = {
  name: "fluffy"
};

function getName(cat) {
  return cat.name;
}

var name = my_cat.name;

export {
  my_cat ,
  getName ,
  name ,
}
/* name Not a pure module */

Some other quick example:

// rescript
let n = 1 + 1
// outputs
let n = 2

// rescript
let n = 1.0 +. 1.0
// outputs
let n = 1.0 + 1.0

// rescript
let t1 = [1, 2, 3][0]
// outputs 
let t1 = 1

// rescript
let t1 = [1, 2, 3]
let t2 = t1[0]
// outputs
var t1 = [
  1,
  2,
  3
];

var t2 = t1[0];

I’m sure there are other example.

Do we have this behavior documented anywhere?

3 Likes

Great idea to gather up all of these cases in one big thread!

Quick reply - this is also very much affected by what’s exposed to the outside world via interface files etc. Add interface files and expose nothing/less than default, and even more optimizations can be applied.

4 Likes

In particular it will not inline values across modules. You’ll see a very different result in a real application. It will still optimise what it can, and more with interface files, but not quite to the extent you’re seeing here.

1 Like