Skip to content

Commit 83c311c

Browse files
authored
Merge pull request rescript-lang#65 from reason-association/part_2
release 8.3 (part 2)
2 parents 1dfa18e + 022ed54 commit 83c311c

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
---
2+
author: hongbo
3+
date: "2020-09-26"
4+
previewImg:
5+
category: compiler
6+
title: What's new in ReScript 8.3 (Part 2)
7+
description: |
8+
---
9+
10+
## Introduction
11+
12+
ReScript is a soundly typed language with an optimizing compiler focused on the JS platform.
13+
It's focused on type safety, performance and JS interop. It used to be called BuckleScript.
14+
15+
[[email protected]](https://www.npmjs.com/package/bs-platform/v/8.3.0) is now available for testing, you can try it via
16+
17+
```
18+
19+
```
20+
21+
Following the [previous post](/blog/release-8-3-pt1), in this post we will go through
22+
the enhancement over the build system.
23+
24+
## Performance enhancement
25+
26+
The underlying build engine for `bsb` is [ninja](https://ninja-build.org/), it is famous for
27+
[being fast](https://www.aosabook.org/en/posa/ninja.html)
28+
to build large C++ repos.
29+
30+
In the last releases, we did lots of work for vertical integration into the bsb build chain.
31+
For example, we replaced the dynamic dependency parser with a minimal specialized one for bsb.
32+
we also removed the static dependencies parser which is only used for parsing C++ compiler output.
33+
34+
Thanks to various other low-level improvements, the final outcome is quite impressive.
35+
For example, The binary size for [Mac platform](https://github.com/ninja-build/ninja/releases/tag/v1.10.1) is 270 KB
36+
while our vendored version is only 136KB. This is a non-trivial gain given that ninja is minimalist and already
37+
optimized by top-level C++ experts.
38+
39+
Note such vertical integration not only brings better performance, smaller sizes, it also brings new features
40+
41+
## Build system enhancements for editor diagnostics
42+
43+
When people are coding in their favorite editors, they expect to see syntax and type errors in real-time.
44+
There are multiple ways to achieve this. The most reliable way is to always invoke the build system whenever the user saves a file. Due to not having an in-memory cache, our build system is very reliable. However we didn't yet optimize the build system for live feedback in editors.
45+
what syntax errors, type checking errors do they have when editing? There are multiple ways to achieve this, the most easy
46+
and reliable way is to always invoke the build system whenever the user saves the files, since it's the same build system
47+
without any in-memory cache, the reliability is very high, however, there's several challenges to use the build system output as editor diagnostics.
48+
49+
### The build system/compiler has to be fast to deliver real-time feedback
50+
51+
Our build system is fast enough to deliver feedback for reasonable sized projects in less than 100ms.
52+
thanks to our previous [hard work](/blog/scalable). We continue improving
53+
Pushing the limits of performance in the build system allows us to provide real-time feedback in editors.
54+
55+
### The warnings for each file should not be flushed during a rebuild
56+
57+
For a typical file based build system, if the file A is compiled successfully with some warnings, the rebuild will not build A anymore.
58+
This is problematic if we use the build system output for editor diagnostics. Since the second build will not capture those warnings, we
59+
could use some caching mechanism to cache previous build output. But… stateful systems are not reliable and come with a whole range of different problems.
60+
61+
To solve such a challenging problem, we did some innovations to co-ordinate the compiler and build system. When the file A is compiled with warnings,
62+
the compiler will produce some marks to the build system, the build system will keep building but such marks are encoded in the build rules
63+
so that the second build will do the rebuild.
64+
65+
The benefit is two fold:
66+
67+
- Rebuild will re-capture those warnings
68+
- Rebuild will be fast since only those files with warnings get rebuilt, it will not trigger unnecessary builds since our build is [content-based](https://rescript-lang.org/blog/scalable) build system.
69+
70+
The integration between compiler and build system is encoded in a specialized protocol. This makes it almost cost-free.
71+
72+
### Notifying clients through .compiler.log
73+
74+
To get the build output, instead of communicating through IPC, we adopted a simple protocol. Whenever a build is done, we write the output to a file called `.compiler.log`.
75+
This makes the editor integration build-system agnostic, it does not need talk to the build system directly.
76+
77+
It also makes our build tool work with other watchers including Facebook's [watchman](https://facebook.github.io/watchman/).
78+
Watchman is a more scalable watcher tool for some specific platforms and less memory hungry, however, we still need a watchman-client to get the output of triggered job.
79+
We write the output to `.compiler.log` per each build, allowing clients to read compiler diagnostics when they want.
80+
81+
## A better algorithm for removing stale outputs
82+
83+
Whenever we rename a file, e.g. `a.res` to `b.res`, will lead to the output of `a.res` being stale. Thanks to the deeper integration of the build system and compiler,
84+
we employ a more advanced strategy to remove stale outputs in this release. Pruning stale outputs is done in the beginning of each build.
85+
86+
There are two ways of removing staled artifacts, the second one is introduced in this release:
87+
88+
- Based on live analysis and prebuilt-in knowledge
89+
90+
We scan `lib/bs` directory and check some dangling cm{i,t,j,ti} files, if it does not exist in
91+
the current build set, it is considered stale artifacts. If it is `cmt` file, it would trigger some hooks of `genType`, notably -cmt-rm.
92+
93+
- Based on previous build logs
94+
We store previous compilation stats. If a file is in the previous compiler output, but no longer in the output of the new build, it is considered stale and can be removed.
95+
it is considered stale output which can be removed.
96+
97+
In general, strategy two is more reliable and efficient.
98+
99+
- We don't need to recompute the path since it is already done by the build system.
100+
- When we change the in-source build to out-source build, it will still do the pruning properly
101+
102+
However, strategy one is easier for tooling like `genType`. Not every tool has knowledge of the build system.
103+
104+
105+
Sometimes a combination of both strategies is needed.
106+
- When removing .cm* files, we use the first strategy.
107+
- When removing generated javascript, we use strategy two,
108+
109+
110+
111+
Happy Hacking!

index_data/blog_posts.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"release-8-3-pt2": "2020-09-25-release-8-3-2.mdx",
23
"release-8-3-pt1": "2020-09-25-release-8-3.mdx",
34
"new-rescript-logo": "2020-08-28-new-rescript-logo.mdx",
45
"bucklescript-is-rebranding": "archive/bucklescript-is-rebranding.mdx",

0 commit comments

Comments
 (0)