|
| 1 | +--- |
| 2 | +author: hongbo |
| 3 | +date: "2020-02-09" |
| 4 | +previewImg: |
| 5 | +category: compiler |
| 6 | +title: ReScript 9.0 |
| 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/9.0.0) is now available, you can try it via |
| 16 | + |
| 17 | +``` |
| 18 | + |
| 19 | +``` |
| 20 | + |
| 21 | +The changes are listed [here](https://github.com/rescript-lang/rescript-compiler/blob/master/Changes.md#90). |
| 22 | + |
| 23 | +We will go through some highlighted user visible changes. |
| 24 | + |
| 25 | +### Customized light weight stdlib |
| 26 | + |
| 27 | +This is a long-awaited [feature request](https://github.com/rescript-lang/rescript-compiler/pull/2171). |
| 28 | + |
| 29 | +Since this release, users can add such lines in bsconfig.json to make our compiler pakcage a dev dependency. |
| 30 | + |
| 31 | +```json |
| 32 | +"external-stdlib" : "@rescript/std" |
| 33 | +``` |
| 34 | + |
| 35 | +Our current compiler package is quite large since it ships both prebuilt compilers for 3 major platforms |
| 36 | +and the standard library. With this configuration, the compiler will generate js files on top of `@rescript/std` so that |
| 37 | +the compiler package is not needed after the JS files are generated. This is helpful if you want to export ReScript based |
| 38 | +libraries to JS users while not asking JS users to install a large dependency. |
| 39 | + |
| 40 | +Caveat: make sure the version of `@rescript/std` is the same as `bs-platform`, use this configuration only when the package size |
| 41 | +is indeed a problem for you. |
| 42 | + |
| 43 | +### Zero-cost bundle size when adding ReScript |
| 44 | + |
| 45 | +We keep generating code that is friendly for tree-shaking during each releases. |
| 46 | +We believe we reach a milestone that ReScript adds close to zero cost to your bundler |
| 47 | +size unlike many other programming languages compiled into JS; the bundled code is almost ReScript runtime free and |
| 48 | +the generated library code is fits the tree-shaking principle very well. |
| 49 | + |
| 50 | +To demonstrate what we achieved, we made a [repo](https://github.com/bobzhang/zero-cost-rescript) so that |
| 51 | +you can try it and see how good the bundled code is. |
| 52 | + |
| 53 | + |
| 54 | +### Improved code generation for pattern match |
| 55 | + |
| 56 | +We continue improving the quality of generated code in this release. |
| 57 | + |
| 58 | +Take this [issue](https://github.com/rescript-lang/rescript-compiler/issues/4924) for example, for pattern match as below: |
| 59 | + |
| 60 | +```res |
| 61 | +let test = x => |
| 62 | + switch x { |
| 63 | + | NoArg => true |
| 64 | + | _ => false |
| 65 | + } |
| 66 | +``` |
| 67 | + |
| 68 | +It used to generate code as below: |
| 69 | + |
| 70 | +```js |
| 71 | +function test(x) { |
| 72 | + if (typeof x === "number") { |
| 73 | + return x === 0; |
| 74 | + } else { |
| 75 | + return false; |
| 76 | + } |
| 77 | +} |
| 78 | + |
| 79 | +``` |
| 80 | +Now it is simplified as |
| 81 | +```js |
| 82 | +function test(x){ |
| 83 | + return x === 0 |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +This is possible is that our optimizer will try to analyze several predicates and get rid of redundant predicates, |
| 88 | +more diffs could be found [here](https://github.com/rescript-lang/rescript-compiler/pull/4927/files?file-filters%5B%5D=.js). |
| 89 | + |
| 90 | +Another important improvement is that we fixed the pattern match offset issue, the consequence is that |
| 91 | + magic number will not be generated |
| 92 | +for complex pattern matches any more, below is a represenative diff thanks to this clean up: |
| 93 | + |
| 94 | +```diff |
| 95 | +function is_space(param){ |
| 96 | +- var switcher = param - 9 | 0; |
| 97 | +- if (switcher > 4 || switcher < 0) { |
| 98 | +- return switcher == 23 ; |
| 99 | ++ if (param > 13 || param < 9) { |
| 100 | ++ return param === 32; |
| 101 | + } else { |
| 102 | +- return switcher !== 2; |
| 103 | ++ return param != 11; |
| 104 | + } |
| 105 | +} |
| 106 | +``` |
| 107 | + |
| 108 | +### Syntax changes |
| 109 | + |
| 110 | +We introduced two minor tweaks for the concrete syntax. |
| 111 | + |
| 112 | +- guard in pattern matching is recommended to use `if` instead of `when` |
| 113 | + |
| 114 | +```res |
| 115 | +switch expr { |
| 116 | + | pat if predicate => // was: pat when predicate |
| 117 | +} |
| 118 | +``` |
| 119 | + |
| 120 | +`when` is still supported but it will be deprecated in the future. |
| 121 | + |
| 122 | +- explicit nested object literal syntax |
| 123 | + |
| 124 | + |
| 125 | +`{"keya" : {keyb : 3 } }` used to be interpreted as `{"keya" : {"keyb" : 3 } } `, such implicity makes |
| 126 | +us not able to embed regular records inside JS object literals. Since this release, |
| 127 | +user has to write JS object literals explicitly and `{"keya" : {keyb : 3}}` will be interpreted as a regular |
| 128 | +record inside a js object literal. More discussions can be found [here](https://forum.rescript-lang.org/t/fixing-the-semantics-of-nested-objects-breaking-changes/976). |
| 129 | + |
| 130 | + |
| 131 | +Note there are some pretty interesting internal changes in this release -- for example, using WASM to replace Camlp4 and a |
| 132 | +generalized visitor pattern without using objects -- that we will discuss in a separate post |
| 133 | + |
| 134 | +Happy Hacking! -- Hongbo Zhang |
0 commit comments