-
-**After:**
-
-
-
-Please see [Better Data Structures Printing (Debug
-Mode)](/docs/reason-compiler/latest/better-data-structures-printing-debug-mode) for usage.
-
-## Even Better `bs.deriving abstract`
-
-We've further polished our new way of binding to JS objects. The record fields
-of a `bs.deriving abstract` can now accept functions.
-
-## Pipe First Improvement
-
-[Pipe First](/docs/manual/latest/pipe) now supports piping into variant tags!
-
-```reason
-let result = name |. preprocess |. Some
-```
-
-We turn this into:
-
-```reason
-let result = Some(preprocess(name))
-```
-
-### Js.Boolean Is Gone
-
-Since BuckleScript 3.0, OCaml `bool` now compile to JS `boolean`. It was
-deprecated (all the boolean conversion functions became no-ops, with warnings
-during build), and now completely removed. No more need for the converter
-functions!
diff --git a/_blogposts/archive/2018-05-23-bucklescript-release-3-1-4.mdx b/_blogposts/archive/2018-05-23-bucklescript-release-3-1-4.mdx
deleted file mode 100644
index d3cf03167..000000000
--- a/_blogposts/archive/2018-05-23-bucklescript-release-3-1-4.mdx
+++ /dev/null
@@ -1,21 +0,0 @@
----
-author: hongbo
-date: "2018-05-23"
-previewImg:
-badge: release
-title: Announcing BuckleScript 3.1.4
-description: |
----
-
-## New Release
-
-Hey again! The release two days ago removed the deprecated Js Boolean APIs (no
-longer needed since we compile OCaml booleans to JS boolean since `3.0.0`). But
-folks have voiced that the removal was too hasty, as some of their dependencies
-still haven't upgraded to `3.0.0` and thus still needed the deprecated APIs.
-
-We try to be diligent with our releases; hopefully this didn't churn too many
-people. To remediate the situation, **we're putting those calls back for this
-version**. Finger crossed that you don't have to wait on too many dependencies!
-
-Sorry for the small churn, and thanks for all your feedback!
diff --git a/_blogposts/archive/2018-07-17-bucklescript-release-4-0-0-pt1.mdx b/_blogposts/archive/2018-07-17-bucklescript-release-4-0-0-pt1.mdx
deleted file mode 100644
index 3c3e637df..000000000
--- a/_blogposts/archive/2018-07-17-bucklescript-release-4-0-0-pt1.mdx
+++ /dev/null
@@ -1,106 +0,0 @@
----
-author: hongbo
-date: "2018-07-17"
-previewImg:
-badge: release
-title: Announcing BuckleScript 4.0 (Part One)
-description: |
----
-
-## Newest Changes
-
-`bs-platform` 4.0.0 is released! It has some nice features that we want to
-share with you, a more detailed list of changes is available
-[here](https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#400)
-
-In this post, I will talk about a new development workflow, all toolchains are
-self-contained in `bs-platform`, [Cristiano](https://twitter.com/ccrisccris)
-will talk about the new runtime encoding for optional.
-
-### A simple approach to accelerate feedback loop in a reliable way
-
-For mordern day-to-day development, developers expect that whenever files are
-changed, the build process is re-triggered automatically and browser reloaded
-instantly, this feedback loop should be quick enough to make developers not get
-distracted.
-
-What we have before this release is as below:
-
-- Source file changes detected by bsb watch mode, rebuild
-- Webpack noticed JS files modified, rebundle and update the browser state
-
-Both `bsb` and `webpack` has a watch mode, but they are architectured in
-fundamentally different ways that they achive different levels of reliability.
-
-In `bsb` watch mode, there is no long running memory-hungry process, so
-whenever a file changed, a fresh process is started very fast and dies quickly,
-our experiment shows that in practice, a long running bsb process can work for
-a week without going into bad state, and such feedback loop is still instant.
-
-`Webpack` holds lots of objects in memory and running for a longtime, it
-results in less reliability and OOM from time to time.
-
-Another complexity introduced by a JS bundler is that it explodes users
-directory structure, for beginners trying to get started with bucklescript,
-installing such huge amount of directories is intimidating. In a slow network,
-this used to result in installation failure.
-
-We understand that existing JS bundler has a huge ecosystem and it is
-invaluable in production mode, but we are exploring whether we can provide
-similar or even more reliable development experience without introducing such
-complexity.
-
-Below is a new workflow we are exploring in this release:
-
-### NodeJS module loader in browser
-
-Instead of bundling the modules like normal bundlers, we provide a NodeJS
-module loader so that it simply reloads the module without bundling.
-
-Note ideally this can be achieved using ES6 module spec, however, it is not
-practical due to following reasons:
-
-- Most dependencies are not strictly ES6 compilant, this is true even for libraries authored in ES6 style
-
-```js
-import {createElement} form "react" ; // not es6 compliant
-import {createElement} from "node_modules/react/index" // not es6 compilant
-import {createElement} from "./node_modules/react/index.js" // correct es6 module
-```
-- ES6 modules does not allow an indirection, by introducing our own NodeJS module loader, we have an indirection and more meta-data about each module, so that we can do more reflection work in the future.
-
-Loading in clean state without packing seems to introduce some redundant work,
-but on the contratry, it is very fast, it used to load 200 modules under 150ms,
-even better, since there is no cached state in a long running process, it is
-much more reliable.
-
-### WebSocket integration with bsb
-
-We need a mechanism to communciate between browser and the build system so that
-whenever a rebuild finished, the browser get notified.
-
-Instead of introducing more dependencies, we implemented a minimal websocket
-interface so that whenever a rebuild finishes, the weboscket clients which
-subscribe the port will get notified.
-
-## To conclude and try it out
-
-So the proposed new work flow is as below: whenever a source file is changed,
-the bsb rebuild, if it build successfully, it will notify the browser to reload
-the NodeJS modules directly.
-
-All the devtools are provided by bs-platform, the good thing is that there is
-no long running memory-hungry process, so that we expect it will deliver a more
-reliable and consistent experience.
-
-You can try it out in `bs-platform@4.0.0`
-
-```sh
-bsb -init test -theme react-lite
-cd test
-npm install
-npm start
-http-server # start a http server
-```
-
-Open `localhost:port/index.html`, changes the reason source code and expect the browser show the changes.
diff --git a/_blogposts/archive/2018-07-17-bucklescript-release-4-0-0-pt2.mdx b/_blogposts/archive/2018-07-17-bucklescript-release-4-0-0-pt2.mdx
deleted file mode 100644
index 943db6237..000000000
--- a/_blogposts/archive/2018-07-17-bucklescript-release-4-0-0-pt2.mdx
+++ /dev/null
@@ -1,45 +0,0 @@
----
-author: hongbo
-date: "2018-07-17"
-previewImg:
-badge: release
-title: Announcing BuckleScript 4.0 (Part Two)
-description: |
----
-
-## New Changes
-
-`bs-platform` 4.0.0 introduces a new runtime representation for optionals.
-
-While beforehand `None` was represented at runtime as `0` and `Some("hello")`
-as an array `["hello"]`, the new representation tries to unbox optionals as
-much as possible.
-
-Now `None` is represented as `undefined` and `Some("hello")` simply as
-`"hello"`.
-
-Generally speaking, `Some(v)` is represented as `v`, i.e. unboxed. The only
-exception is when `v` itself is `None` or `Some(...(Some(None))`, in which case
-a special boxed representation is used.
-
-The construction of new values `Some(-)`, and pattern matching `| Some(-) =>
-...`, perform some case analysis to decide when to box or unbox values. In the
-absence of nested optionals, the result of both operations will *always* be the
-indentity.
-
-Because of that, it's possible to use type-based optimization to avoid
-performing case analysis in the first place. So while the generic function
-```(x) => Some(x)``` will generate code to check wheter `x` should be boxed,
-the more type-specific function ```(x:int) => Some(x)``` is just compiled as
-the identity function, as it's clear from the type that no boxing is required.
-
-For a high-level formalization of the boxing and unboxing operations, as well
-as the polymorphic comparison functions, see this
-[gist](https://gist.github.com/cristianoc/791aac26f94dbded0fc137d61f4bd2a8).
-
-One design choice was whether to represent `None` as `null` or as `undefined`.
-The choice of `undefined` was made because this allows a direct mapping for
-[optional labeled
-arguments](https://reasonml.github.io/docs/en/function#optional-labeled-arguments).
-As a consequence `null` is never boxed, so e.g. `Some(null)` is represented as
-`null`.
diff --git a/_blogposts/archive/2018-11-13-arity-zero.mdx b/_blogposts/archive/2018-11-13-arity-zero.mdx
deleted file mode 100644
index 20f10a62f..000000000
--- a/_blogposts/archive/2018-11-13-arity-zero.mdx
+++ /dev/null
@@ -1,94 +0,0 @@
----
-author: hongbo
-date: "2018-11-13"
-previewImg:
-title: A Change of Undefined Behavior in BuckleScript 4.0.7
-description: |
----
-
-## What is this about?
-
-In the latest BuckleScript release, we introduced a minor change in the codegen
-which broken some user libraries. Note this change only broke the code in the
-FFI boundary(the interop between JS).
-
-In the early days of BuckleScript, there is no built-in uncurried calling
-convention support, since OCaml is a curried language, which means every
-function has arity one, so there is no way to express that a function has arity
-zero, this makes some interop challenging. In the mocha unit test library, it
-expects its callback to be function of arity zero.
-
-To work around this issue, before this release, we did a small codegen
-optimization, for a function of type `unit -> unit`, if its argument is not
-used, we remove its argument in the output.
-
-```reason
-let f: unit => int = () => 3;
-let f_used: unit => unit = x => Js.log(x);
-```
-
-Output JS prior to v4.0.7:
-
-```js
-function f (){
- return 3
-}
-function f_used (x){
- console.log(x)
-}
-```
-
-To make this hack work, in the application side, for a curried function
-application, we treat the function of arity 0 and arity 1 in the same way, this
-still works since curried function application could only happen on the ocaml
-function.
-
-This trick is unintuitive, it makes code generated less predictable and it is
-not relevant any more, since we added native uncurried calling convention
-support later.
-
-Therefore, we generate JS code in a more consistent style in this release:
-
-```reason
-let f: unit => int = () => 3;
-```
-
-```js
-function f (param){
- return 3
-}
-```
-
-So in your FFI code, if you have a callback which is expected to be of arity
-zero, use `unit -> unit [@bs]` or `unit -> unit [@bs.uncurry]`, it is 100%
-correct. Note our previous trick will only make `unit -> unit` work most time,
-but it can not provide any guarantee.
-
-Since we removed the trick, the curried runtime does not treat function of
-arity 0 and arity 1 in the same way, so if you have code like this
-
-```reason
-let f: unit => int = [%bs.raw {|function () {
- return 3
-}|}];
-```
-
-It is not correct any more, the fix would be:
-
-```reason
-let f: unit => int = [%bs.raw {|function(param) {
- return 3
-}|}];
-```
-
-Or
-
-```reason
-let f: (. unit) => int = [%bs.raw {|function() {
- return 3
-}|}];
-```
-
-FFI is a double edge sword, it is a must have to ship your product, yet it is
-tricky, and there may be some undefined behavior you rely on but don't
-recognize, it is encouarged to always test your FFI in the boundary.
diff --git a/_blogposts/archive/2018-11-19-bucklescript-roadmap-q3-4-2018.mdx b/_blogposts/archive/2018-11-19-bucklescript-roadmap-q3-4-2018.mdx
deleted file mode 100644
index fe24b349d..000000000
--- a/_blogposts/archive/2018-11-19-bucklescript-roadmap-q3-4-2018.mdx
+++ /dev/null
@@ -1,84 +0,0 @@
----
-author: hongbo
-date: "2018-11-19"
-previewImg:
-badge: roadmap
-title: BuckleScript Plans for the Second Half of 2018
-description: |
----
-
-## Introduction
-
-In this article we will explain what we are doing now and what we plan to
-improve in next half (Dec-May), we would also like to hear your feedback so
-that we can adjust accordingly.
-
-Keep in mind that the development team is a very small team, so we have to
-prioritize things instead of working on every feature.
-
-## What we are doing
-
-In the last couple of month we are busy upgrading the OCaml compiler from
-4.02.3 to 4.06.1, the good news is that the upgrade is almost done.
-
-We plan to ship it soon by the end of this year, at the same time, we will
-still maintain the current version of the compiler until we feel the new
-compiler is as good as the old one.
-
-Note the upgrade is not easy work since the internals of OCaml compiler changed
-significantly in the last few years. Our upgrade strategy is also quite
-conservative, it works by conditional compilation so that the bsc compiler
-actually work with both versions, the benefit is that in this case, we are not
-in a messy state, the bug fix of bsc compiler can still benefit two branches.
-
-But the reward is also huge, there are a bunch of optimizations and nice
-features coming alone in the recent releases of the OCaml language, to name a
-few: `inline records`, `local exception` and `hex notation for floats` etc.
-More importantly, this is a great move to engage better with OCaml ecosystem:
-the previous old version compiler imposed some maintenance overhead for OCaml
-toolchain, we can make better use of OCaml toolchain after such upgrade.
-
-## What's next
-
-### Making better use of the new compiler internals
-
-The upgrade is divided into two stage, the first stage is focused on `no
-regression` so that we can ship it.
-
-Afterwards, we have plans to make better use of the more info rich IR in the
-new release. Thanks to the flambda introduced after OCaml 4.03, more
-information is passed down to the lambda IR where BuckleScript take from. For
-example, user can annotate functions inline or not with inline attribute, we
-can make better use of such information.
-
-In newer versions of OCaml compiler, the block and array is more distinguished
-we will investigate whether we can make use of it to provide better data
-representation for OCaml datatype.
-
-Another interesting direction is to see if we can encode module in a consistent
-style: as an JS dictionary for both global modules and local modules.
-
-### Improving the usability of BuckleScript toolchain
-
-BuckleScript is focused on making better use of JS ecosystem and provide
-values to ship JS code in production (produced by BuckleScript).
-
-
-
-#### Making Bucklescript toolchain more lightweight
-
-Currently it is still too heavy for users to provide JS libraries from
-BuckleScript, since clients need to install bs-platform which requires a lot of
-disk-space and native compilation in some platform. We will investigate if we
-can distribute the native compiler without using npm.
-
-Separate the compiler from stdlib may also help draw the contribution to the
-stdlib/belt library.
-
-#### Improving the usability of bsb
-
-Currently the bsb is restricted by the npm directory layout, the generated JS
-artifacts is also restricted by it, we will see if we can relocate the JS
-artifacts or provide more flexibility for users.
-
-
diff --git a/_blogposts/archive/2018-12-05-bucklescript-release-4-0-8.mdx b/_blogposts/archive/2018-12-05-bucklescript-release-4-0-8.mdx
deleted file mode 100644
index faaf13c0a..000000000
--- a/_blogposts/archive/2018-12-05-bucklescript-release-4-0-8.mdx
+++ /dev/null
@@ -1,95 +0,0 @@
----
-author: hongbo
-date: "2018-12-05"
-previewImg:
-badge: release
-title: BuckleScript 4.0.8 (Part One)
-description: |
----
-
-## New Release
-
-Today we released version 4.0.8 of `bs-platform`.
-A detailed list of changes is available
-[here](https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#408).
-
-Most user-facing changes are bug fixes and small enhancements, while quite a
-lot of work has been done behind the scenes towards the more fundamental
-improvements coming down the line. This blog post refers to the BuckleScript
-runtime and some of the work we are doing to improve it.
-
-The design goal of BuckleScript is to make the runtime as small as possible.
-This runtime is divided into two parts: the C shims, and the fundamental
-language feature support.
-
-The C shims are not a strict runtime requirement: in the native backend, the
-functions are implemented in C, but in BuckleScript this isn't necessary. We
-can either implement the C shims in a polyfill style or we can just implement
-them in OCaml and compile via BuckleScript. Recently, we have been shifting
-more and more work from the runtime to the normal OCaml stdlib by patching it
-with conditional compilation. The benefit is obvious – they are just normal
-functions which do not need special compiler support – but the downside is that
-we might need to make more patches to the libraries which use C functions, but
-considering the more challenging part of maintaining the patches to the
-compiler, we think such overhead is worthwhile.
-
-If we ignore the C shims, the BuckleScript runtime is very small, and it is
-pretty easy for experienced BuckleScript programmers to write runtime-free code
-which generates standalone JS code. Such code could include supporting curried
-calling conventions, encoding of OCaml ADT, etc.
-
-The BuckleScript runtime is written in BuckleScript itself. The benefit of this
-is that it is much more maintainable than implementing in JS itself, and it is
-easier to keep some invariants when crossing the boundary between the runtime
-and the stdlib. For example, we don't need to worry about the consistency of
-the runtime encoding of `type tuple` in BuckleScript, since the runtime is also
-implemented in BuckleScript itself, and we get three output modules for free
-thanks to this "dogfooding".
-
-However, this makes the build system pretty complicated and fragile, and the
-dependencies between each module are mostly hard coded. Even worse, this
-introduces a hard dependency between the normal libraries and the runtime
-binary artifacts.
-
-In particular, one
-[issue](https://github.com/BuckleScript/bucklescript/issues/2772) we want to
-address is to make the BuckleScript toolchain lightweight. We will continue to
-implement the BuckleScript runtime by using BuckleScript itself, but we want to
-get rid of dependencies like [the support for
-exceptions](https://github.com/BuckleScript/bucklescript/issues/3164). In the
-end, installation will no longer involve building the runtime: BuckleScript
-will simply be a bunch of generated JS files, so the complexity of the build
-system will not impact users at all. This is quite important given that we are
-committed to supporting Windows.
-
-In the future, we will therefore be able to distribute the runtime as a normal
-JS library, and the BuckleScript user will only need the binary compiler and a
-small set of JS files. They will be able to use stdlib, Belt or anything else.
-
-To get rid of such dependencies between stdlib and the runtime, we are going to
-introduce a breaking change in the future. In hindsight, our support for
-catching JS exceptions exposed the concrete representation of the exception
-encoding, in particular:
-
-```ocaml
-match ... with
-| OCamlException exn -> ..
-| Js.Exn.Error e -> ...
-```
-
-In this release, we introduced a function to avoid exposing such exception constructors:
-
-```ocaml
-match ... with
-| OCamlException exn -> ...
-| e ->
- match Js.asJsExn e with
- | Some jserror -> ..
- | None -> ...
-```
-
-We encourage you to make such changes yourself to future-proof your codebases.
-
-Oh and by the way, one side effect of this refactoring of the BuckleScript
-runtime is that the compilation does not require reading of the generated
-`.cm*` files, which means faster compilation :)
diff --git a/_blogposts/archive/2019-01-07-bucklescript-release-4-0-17.mdx b/_blogposts/archive/2019-01-07-bucklescript-release-4-0-17.mdx
deleted file mode 100644
index 694af4b66..000000000
--- a/_blogposts/archive/2019-01-07-bucklescript-release-4-0-17.mdx
+++ /dev/null
@@ -1,30 +0,0 @@
----
-author: hongbo
-date: "2019-01-07"
-previewImg:
-badge: release
-title: Announcing BuckleScript 4.0.17
-description: |
----
-
-## Newest Changes
-
-`bs-platform` 4.0.17 is a major release.
-
-It improved incremental compilation time significantly.
-
-A picture is worth a thousand words, below is a large monorepo which contains
-4096 modules, changing the root node which has more than 3000 dependents, it
-finished building within 400ms.
-
-
-
-We will write a dedicated article explaining how we achieve this incredible
-build performance.
-
-A detailed list of changes is available
-[here](https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#4017)
-
-Another quite important but not client facing change is that we renovated the
-internal build system, it will be much easier for contribution later on. We
-will update the contribution guide once it gets stable.
diff --git a/_blogposts/archive/2019-01-11-scalable.mdx b/_blogposts/archive/2019-01-11-scalable.mdx
deleted file mode 100644
index 5950c2128..000000000
--- a/_blogposts/archive/2019-01-11-scalable.mdx
+++ /dev/null
@@ -1,277 +0,0 @@
----
-author: hongbo
-date: "2019-01-11"
-previewImg:
-title: In search of lightning feedback loop in a large codebase
-description: |
----
-
-## Feedback loops
-
-As software developers, when we touch a codebase, we want the edit-compile
-cycle, to be as short as possible. Studies show that feedback loop less than
-1s, or 100ms will prevent devleopers getting distracted.
-
-This seems to be possible in a small project, but as project grows to 10k
-files, or even more, 100k files in a large company like Google, Facebook, this
-seems to be extremely challenging.
-
-In this article, we are talking about how BuckleScript - it supports both OCaml
-and ReasonML syntax - is trying to solve this issue.
-
-The edit-build cycle in BuckleScript consists of two components: the compiler
-which does type checking and code generation and the scheduler which figures
-out what to rebuild and how to do it concurrently.
-
-## The importance of compiler's cold performance
-
-In order to reduce the edit-build latency, some languages adopt an approach of
-in memory compiler + watch mode. We think this is not a scalable or reliable
-approach.
-
-A compiler is a complex piece of software, the chance that a compiler has
-memory leak is not low. It is not observed in real world since compiler is used
-mostly in a short-lived setting, it starts up fast and dies off quickly.
-
-However, this is decimated when compiler is put in server mode. When we have
-10k or 100k files held in memory, it is very easy to observe OOM (out of memory
-issues).
-
-We figured that to deliver a scalable and reliable system, it is better to
-decouple the compiler's complexity from the scheduler. When the compiler cold
-starts and dies off quickly, the operating system process mechanism serves as
-an obviously correct garbage collector, which increases the reliability of the
-whole system.
-
-To reduce such latency in a single compiler's workload, we spent lots of time
-tweaking the performance of the compiler itself, for example, rewriting the hot
-path in C code, most BuckleScript compiler source code is written in an
-imperative C-style to avoid allocation.
-
-To have a general idea of how fast BuckleScript's compiler runs:
-
-```
-test>cat fib.ml
-let rec fib = function
- | 0 | 1 -> 1
- | n -> fib (n - 1) + fib (n - 2)
-```
-
-```
-test>time /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-cmi -bs-cmj -c fib.ml
-
-real 0m0.008s
-user 0m0.004s
-sys 0m0.003s
-```
-
-Having a compiler run fast with a cold start lays the groundwork so that it
-won't be the bottleneck in the whole process. This is because when the
-architecture decouple the compiler from the scheduler, the compiler will be
-invoked by the scheduler hunderds of thousands of times in a build cycle, the
-latency of the compiler in a single compilation unit will add up.
-
-## The art of being incremental
-
-Having a compiler running fast in cold mode does not solve the scalability
-issue alone. Take a code base which contains 100K source files for example,
-100ms per file would result in 10,000s latency which is not acceptable. To
-solve such issue, we need reduce the workload as much as possible during each
-edit-build cycle.
-
-In a statically typed language, suppose we have two compilation units A , B,
-and B depends on A. Whenever A changes, B gets recompiled, to make it worse,
-the recompilation propogates, all dependencies of B get recompiled, which will
-result in a snowball effect. In this model, whenever we touch the non-leaf
-compilation unit, the latency would be large.
-
-The key observation here for BuckleScript is that B does not really depend on
-the last modified time of A, it depends on the intermediate output of A (e.g,
-`.cmj` and `.cmi` file) which may not change even if we modify A. What we work
-on here is to reduce the probability of changing A's intermediate output due to
-changing A. With the integration of a scheduler, it can help stop the
-propagation as early as possible.
-
-In BuckleScript, each compilation unit is composed of two files, the
-implementation file and interface file which are compiled to intermediate
-output .cmj and .cmi separately.
-
-The interface builds are completely separate from implemetation, it does not
-depend on .cmj (implementation intermediate output) at all.
-
-Suppose the interface is not changed, whenever we touch the implementation
-file, BuckleScript designs the data structure of `.cmj` in a way that the
-content of `.cmj` is seldom changed. (Let's say its probability is 0.05 which
-is rare in cases when the arity of a function changed)
-
-If neither `.cmj` nor `.cmi` gets changed, the scheduler would stop
-propagation.
-
-Suppose the `.cmj` file is still changed (P = 0.05), A's dependency B would get
-recompiled. Note `B.cmi` only depends on `A.cmi`, so it will not get compiled,
-only `B.cmj` will get recompiled, its chances that `B.cmj` gets changed will be
-even lower. In practice, the probabiity of the length of propagation chain is
-more than two is less than
-
-```
-0.05 * 0.05 = 0.0025
-```
-
-This means when we are in an edit-build cycle, whenever A gets changed, it may
-have many direct dependencies, but the longest rebuild sequence will get
-settled in at most two compilation units. Suppose the scheduler schedule the
-tasks in parallel, the longest sequence is bound by two, which means the
-rebuild cycle is very close to compiling two compilation units.
-
-In implementation, we also generalized the idea of stopping propogation of .cmi
-changes, so whenever we are adding some comments in the interface file, it will
-get settled quickly.
-
-The worst case is that the root of an interface changed. In such case, it does
-not mean all its dependencies will get recompiled, it depends on how many
-dependencies' interface depend on the root's interface. The cool thing is that
-since interface's dependency chain is completely decoupled from
-implementation's dependency, actually it used to be a subset of
-implementation's dependency chain, so only a subset of its dependencies will
-get compiled. We will see a concrete an example later.
-
-
-## A fast scheduler
-
-As we said, the time spent in an edit-build cycle is mostly composed of two
-parts: compiling invoking the compiler, scheduling.
-
-We are reusing the very fast scheduler provided by
-[Ninja](https://ninja-build.org/manual.html)
-
-> Where other build systems are high-level languages, Ninja aims to be an
-> assembler.
-
-BuckleScript outputs assembler style instructions consumed by Ninja which does
-scheduling very fast and provides good parallelism. By integrating with Ninja's
-`restat` attribute, we are able to implement the idea of a specialized content
-based build system.
-
-It is fast enough for 99% of use cases. For a project less than 1k files, the
-time spent in an edit-build cycle is dominated by the compiler, but as project
-grows to 10K files or even more, the time spent in compiler is stable and
-bounded due to our incremental design, however, the time will start be
-dominated by the scheduler.
-
-For a nop build around 10k files, it takes around 700ms for Ninja to figure out
-nothing needs to be rebuilt.
-
-The current Ninja model is simple, every time it is invoked, it will re-read
-build.ninja instructions, check stats of artifacts and do the scheduling.
-
-Instead of making a long-lived compiler, we propose to have a long-lived
-scheduler. The complexity of a scheduler is significantly lower than a
-compiler. Having an in-memory scheduler will help reducing redundant work such
-as parsing build.ninja instructions which is around of size 2M for 10k files.
-With the integration of watch mode, it does not need stat all artifacts each
-time, this should help increase the scalability of scheduler to 100K files or
-even more.
-
-## Tests on a synthetic benchmark
-
-Our synthetic bench is borrowed from
-[OMake](http://blog.camlcity.org/blog/omake1.html) and public available
-[here](https://github.com/bucklescript/bsb-bench).
-
->The benchmark has these characteristics: The task is to build n^2 libraries
->with n^2 modules each (for a given small number n), and the dependencies
->between the modules are created in a way so that we can stress both the
->dependency analyzer of the build utility and the ability to run commands in
->parallel.
-
-We modified the benchmark to add interface file for each implementation file.
-
-The benchmark is running on MacBook Pro 18 with CPU 2.6 GHz Intel Core i7,
-Memory 32 GB 2400 MHz DDR4
-
-The test is running against `n = 3,5,7,9`, where the source code size would be
-`2*3^4=162`, `2*5^4=1250`, `2*7^4=4802`, `2*9**4=13122`.
-
-Below is what we get for a cold build from scratch:
-
-| Source size | Clean build (ms) |
-|-------------|------------------|
-| 0162 | 684 |
-| 1250 | 5,100 |
-| 4802 | 24,112 |
-| 13122 | 125,248 |
-
-| Source size | Nop build (ms) | Touching root module (m_1_1_1_1.ml) | Touching (m_1_1_1.mli)|
-|-------------|------------------|-------------------------------------|-----------------------|
-| 0162 | 16 | 59 | 54 |
-| 1250 | 79 | 120 | 133 |
-| 4802 | 266 | 369 | 367 |
-| 13122 | 728 | 963 | 962 |
-
-We can see from the table as size grows, the time spent in edit-build cycle shifts from compilation to the scheduler, this is due to the fact that Ninja scheduler does not save the work for each test.
-
-
-| Source size | Adding value to root module (m_1_1_1_1.ml) | Changing root interface|
-|-------------|--------------------------------------------|------------------------|
-| 0162 | 56 | 70 |
-| 1250 | 131 | 155 |
-| 4802 | 370 | 428 |
-| 13122 | 969 | 991 |
-
-The verbose build log for adding values on source of size `13122` is as below:
-
-```sh
-test9>ninja -C lib/bs -v
-ninja: Entering directory `lib/bs'
-[1/2] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -w -30-40+6+7+27+32..39+44+45+101 -nostdlib -I '/Users/hongbozhang/git/bsb-bench/test9/node_modules/bs-platform/lib/ocaml' -color always -c -o src/dir_1_1/m_1_1_1_1.mlast -bs-syntax-only -bs-binary-ast /Users/hongbozhang/git/bsb-bench/test9/src/dir_1_1/m_1_1_1_1.ml
-[2/2] /usr/local/lib/node_modules/bs-platform/lib/bsb_helper.exe -g 0 -MD src/dir_1_1/m_1_1_1_1.mlast
-[1/5905] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-assume-has-mli -bs-no-builtin-ppx-ml -bs-no-implicit-include -I src/dir_4_6 -I src/dir_4_1 -I src/dir_4_8 -I src/dir_6_5 -I src/dir_6_2 -I src/dir_8_3 -I src/dir_8_4 -I src/dir_2_3 -I src/dir_2_4 -I src/dir_6_3 -I src/dir_4_9 -I src/dir_6_4 -I src/dir_4_7 -I src/dir_2_5 -I src/dir_2_2 -I src/dir_8_5 -I src/dir_8_2 -I src/dir_9_9 -I src/dir_3_7 -I src/dir_1_3 -I src/dir_9_7 -I src/dir_3_9 -I src/dir_1_4 -I src/dir_7_6 -I src/dir_7_1 -I src/dir_5_5 -I src/dir_7_8 -I src/dir_5_2 -I src/dir_3_8 -I src/dir_9_6 -I src/dir_1_5 -I src/dir_9_1 -I src/dir_1_2 -I src/dir_3_6 -I src/dir_9_8 -I src/dir_3_1 -I src/dir_5_3 -I src/dir_5_4 -I src/dir_7_9 -I src/dir_7_7 -I src/dir_8_7 -I src/dir_2_9 -I src/dir_8_9 -I src/dir_2_7 -I src/dir_4_2 -I src/dir_6_8 -I src/dir_4_5 -I src/dir_6_1 -I src/dir_6_6 -I src/dir_2_1 -I src/dir_2_6 -I src/dir_8_8 -I src/dir_8_1 -I src/dir_2_8 -I src/dir_8_6 -I src/dir_6_7 -I src/dir_6_9 -I src/dir_4_4 -I src/dir_4_3 -I src/dir_7_2 -I src/dir_7_5 -I src/dir_5_8 -I src/dir_5_1 -I src/dir_5_6 -I src/dir_1_9 -I src/dir_3_4 -I src/dir_3_3 -I src/dir_9_4 -I src/dir_1_7 -I src/dir_9_3 -I src/dir_5_7 -I src/dir_7_4 -I src/dir_5_9 -I src/dir_7_3 -I src/dir_9_2 -I src/dir_1_1 -I src/dir_9_5 -I src/dir_1_6 -I src/dir_3_2 -I src/dir_1_8 -I src/dir_3_5 -w -30-40+6+7+27+32..39+44+45+101 -nostdlib -I '/Users/hongbozhang/git/bsb-bench/test9/node_modules/bs-platform/lib/ocaml' -color always -o src/dir_1_1/m_1_1_1_1.cmj -c src/dir_1_1/m_1_1_1_1.mlast
-File "/Users/hongbozhang/git/bsb-bench/test9/src/dir_1_1/m_1_1_1_1.ml", line 4, characters 4-5:
-Warning 32: unused value a.
-```
-
-Ignoring the preprocess stage, We can see there are 5906 jobs scheduled but
-only one job is processed. This is because adding a single value does not
-change `m_1_1_1_1.cmj` so that the change of propogation is stopped
-immediately.
-
-The result is surprisingly good even if change the interface of root files, by
-looking at the verbose build log:
-
-```sh
-test9>ninja -C lib/bs -v
-ninja: Entering directory `lib/bs'
-[1/2] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -w -30-40+6+7+27+32..39+44+45+101 -nostdlib -I '/Users/hongbozhang/git/bsb-bench/test9/node_modules/bs-platform/lib/ocaml' -color always -c -o src/dir_1_1/m_1_1_1_1.mliast -bs-syntax-only -bs-binary-ast /Users/hongbozhang/git/bsb-bench/test9/src/dir_1_1/m_1_1_1_1.mli
-[2/2] /usr/local/lib/node_modules/bs-platform/lib/bsb_helper.exe -g 0 -MD src/dir_1_1/m_1_1_1_1.mliast
-[1/5906] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-no-builtin-ppx-mli -bs-no-implicit-include -I src/dir_4_6 -I src/dir_4_1 -I src/dir_4_8 -I src/dir_6_5 -I src/dir_6_2 -I src/dir_8_3 -I src/dir_8_4 -I src/dir_2_3 -I src/dir_2_4 -I src/dir_6_3 -I src/dir_4_9 -I src/dir_6_4 -I src/dir_4_7 -I src/dir_2_5 -I src/dir_2_2 -I src/dir_8_5 -I src/dir_8_2 -I src/dir_9_9 -I src/dir_3_7 -I src/dir_1_3 -I src/dir_9_7 -I src/dir_3_9 -I src/dir_1_4 -I src/dir_7_6 -I src/dir_7_1 -I src/dir_5_5 -I src/dir_7_8 -I src/dir_5_2 -I src/dir_3_8 -I src/dir_9_6 -I src/dir_1_5 -I src/dir_9_1 -I src/dir_1_2 -I src/dir_3_6 -I src/dir_9_8 -I src/dir_3_1 -I src/dir_5_3 -I src/dir_5_4 -I src/dir_7_9 -I src/dir_7_7 -I src/dir_8_7 -I src/dir_2_9 -I src/dir_8_9 -I src/dir_2_7 -I src/dir_4_2 -I src/dir_6_8 -I src/dir_4_5 -I src/dir_6_1 -I src/dir_6_6 -I src/dir_2_1 -I src/dir_2_6 -I src/dir_8_8 -I src/dir_8_1 -I src/dir_2_8 -I src/dir_8_6 -I src/dir_6_7 -I src/dir_6_9 -I src/dir_4_4 -I src/dir_4_3 -I src/dir_7_2 -I src/dir_7_5 -I src/dir_5_8 -I src/dir_5_1 -I src/dir_5_6 -I src/dir_1_9 -I src/dir_3_4 -I src/dir_3_3 -I src/dir_9_4 -I src/dir_1_7 -I src/dir_9_3 -I src/dir_5_7 -I src/dir_7_4 -I src/dir_5_9 -I src/dir_7_3 -I src/dir_9_2 -I src/dir_1_1 -I src/dir_9_5 -I src/dir_1_6 -I src/dir_3_2 -I src/dir_1_8 -I src/dir_3_5 -w -30-40+6+7+27+32..39+44+45+101 -nostdlib -I '/Users/hongbozhang/git/bsb-bench/test9/node_modules/bs-platform/lib/ocaml' -color always -o src/dir_1_1/m_1_1_1_1.cmi -c src/dir_1_1/m_1_1_1_1.mliast
-[2/5906] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-assume-has-mli -bs-no-builtin-ppx-ml -bs-no-implicit-include -I ... -color always -o src/dir_1_1/m_1_1_1_1.cmj -c src/dir_1_1/m_1_1_1_1.mlast
-[3/5906] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-assume-has-mli -bs-no-builtin-ppx-ml -bs-no-implicit-include -I ... -w -30-40+6+7+27+32..39+44+45+101 -nostdlib -I '/Users/hongbozhang/git/bsb-bench/test9/node_modules/bs-platform/lib/ocaml' -color always -o src/dir_1_1/m_1_1_2_2.cmj -c src/dir_1_1/m_1_1_2_2.mlast
-[4/5906] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-assume-has-mli -bs-no-builtin-ppx-ml -bs-no-implicit-include -I ... -color always -o src/dir_1_1/m_1_1_2_1.cmj -c src/dir_1_1/m_1_1_2_1.mlast
-[5/5906] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-assume-has-mli -bs-no-builtin-ppx-ml -bs-no-implicit-include -I ... -color always -o src/dir_1_1/m_1_1_2_3.cmj -c src/dir_1_1/m_1_1_2_3.mlast
-[6/5906] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-assume-has-mli -bs-no-builtin-ppx-ml -bs-no-implicit-include -I ... -color always -o src/dir_1_1/m_1_1_2_9.cmj -c src/dir_1_1/m_1_1_2_9.mlast
-[7/5906] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-assume-has-mli -bs-no-builtin-ppx-ml -bs-no-implicit-include -I ... -color always -o src/dir_1_1/m_1_1_2_4.cmj -c src/dir_1_1/m_1_1_2_4.mlast
-[8/5906] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-assume-has-mli -bs-no-builtin-ppx-ml -bs-no-implicit-include -I ... -color always -o src/dir_1_1/m_1_1_2_5.cmj -c src/dir_1_1/m_1_1_2_5.mlast
-[9/5906] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-assume-has-mli -bs-no-builtin-ppx-ml -bs-no-implicit-include -I ... -color always -o src/dir_1_1/m_1_1_2_6.cmj -c src/dir_1_1/m_1_1_2_6.mlast
-[10/5906] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-assume-has-mli -bs-no-builtin-ppx-ml -bs-no-implicit-include -I ... -color always -o src/dir_1_1/m_1_1_2_7.cmj -c src/dir_1_1/m_1_1_2_7.mlast
-[11/5906] /usr/local/lib/node_modules/bs-platform/lib/bsc.exe -bs-package-name test -bs-package-output commonjs:lib/js/src/dir_1_1 -bs-assume-has-mli -bs-no-builtin-ppx-ml -bs-no-implicit-include -I ... -color always -o src/dir_1_1/m_1_1_2_8.cmj -c src/dir_1_1/m_1_1_2_8.mlast
-```
-
-The log means that there are 5906 jobs to be scheduled but only 11 jobs
-processed. This is because there only 9 direct dependencies, the cmj/cmi
-changes' propogation stops in the first level of dependency, indirect
-dependencies are not propagated any more since the intermediate representation
-stays stable after that. There are 9 more jobs to do compared with changing
-implementation but the latency only increased by 30ms, which means the
-scheduler does a good job in parallelism.
-
-The real world scenario may be a bit worse than our synthetic benchmark, since
-our syntethic benchmark only impose dependencies across implementation files,
-the dependencies across interface files are flat.
-
-To conclude, currently BuckleScript scales very well to projects with around
-10k files, and with some work in improving the scheduler, we believe it is not
-too difficult to scale it to 100K files or even more. To reach such enormous
-scalability in a reliable way, we propose to have a long-lived scheduler and
-fast cold compiler. The language interface design and the design of the data
-structure for the implementation will make the longest rebuild propogation
-chain bounded by two in most cases.
diff --git a/_blogposts/archive/2019-03-01-feature-preview-variadic.mdx b/_blogposts/archive/2019-03-01-feature-preview-variadic.mdx
deleted file mode 100644
index 1d983763a..000000000
--- a/_blogposts/archive/2019-03-01-feature-preview-variadic.mdx
+++ /dev/null
@@ -1,38 +0,0 @@
----
-author: hongbo
-date: "2019-03-01"
-previewImg:
-badge: preview
-title: First-class bs.variadic Support in the Next Release
-description: |
----
-
-## An improved `bs.variadic` decorator
-
-In previous releases, when a `bs.variadic` external (previously called
-`bs.splice` prior to version `4.08`) is present, its tail arguments needed to
-be applied statically. In other words, the `external` marked with
-`bs.variadic`, when used, requires a _literal_ array:
-
-```reason
-[@bs.module "path"][@bs.variadic]
-external join: array(string) => string = "join"
-
-let _ = join([|"a", "b"|]) /* this is ok */
-let f = b => join(b) /* compiler error when you try to abstract `join` */
-```
-
-More importantly, such compilation error was leaky in cases such as this one:
-
-```reason
-let f = join
-```
-
-In the next release, we are going to lift such restriction. You'll be able to
-call an external marked with `bs.variadic` with an array reference, not just a
-literal array.
-
-Caveat: it's unclear how to support such first class `bs.variadic` call in
-conjunction with `bs.new`, so an external declaration that contains both will
-trigger a compilation error. We'll try to figure out this particular case in
-the future too.
diff --git a/_blogposts/archive/2019-03-21-bucklescript-release-5-0.mdx b/_blogposts/archive/2019-03-21-bucklescript-release-5-0.mdx
deleted file mode 100644
index 29b7e4e77..000000000
--- a/_blogposts/archive/2019-03-21-bucklescript-release-5-0.mdx
+++ /dev/null
@@ -1,39 +0,0 @@
----
-author: hongbo
-date: "2019-03-21"
-previewImg:
-badge: release
-title: Announcing BuckleScript 5.0
-description: |
----
-
-## New Changes
-
-`bs-platform@5.0.0` is released! There are quite a few bug fixes in this
-release and refmt is synced up, a detailed list of changes is available
-[here](https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#500).
-
-
-Several new features are introduced in this release:
-
-- first class `bs.variadic` support, documented
- [here](/blog/feature-preview-variadic)
-
-- we prebuilt binaries for Windows, MacOS and Linux, this will help reduce your
- CI build time significantly. For exotic OSes, it will fall back to build from
- source
-
-- bs.deriving light config. For people who prefer short names, we make it
- configurable
-
-```
-[@bs.deriving { abstract: light }]
-type t = {x: int};
-
-let f = (obj: t) => obj->x;
-```
-
-This is the last major release which is targeting OCaml 4.02.3, in the future
-we will make major releases targeting OCaml 4.06.
-
-Happy Hacking!
diff --git a/_blogposts/archive/2019-03-31-bucklescript-release-6-0.mdx b/_blogposts/archive/2019-03-31-bucklescript-release-6-0.mdx
deleted file mode 100644
index 1f1aa7785..000000000
--- a/_blogposts/archive/2019-03-31-bucklescript-release-6-0.mdx
+++ /dev/null
@@ -1,24 +0,0 @@
----
-author: hongbo
-date: "2019-03-31"
-previewImg:
-badge: testing
-title: Announcing BuckleScript 6.0.0-dev.1
-description: |
----
-
-## New Test Release
-
-`bs-platform@6.0.0-dev.1` is released, you can try it with `npm i -g
-bs-platform@next`! (if you have permission issues, try `sudo npm i
---unsafe-perm -g bs-platform@next`)
-
-This is the first release that bucklescript compiler using OCaml 4.06.1
-typechecker.
-
-It also means that most language features from OCaml will trickle down
-automatically.
-
-It is not yet ready for production but we recommend you to try it (esp, new
-OCaml features between 4.02.3 and 4.06.1), note we expect users to have some
-issues in experiment, feedback is welcome!
diff --git a/_blogposts/archive/2019-04-09-bucklescript-release-5-0-1.mdx b/_blogposts/archive/2019-04-09-bucklescript-release-5-0-1.mdx
deleted file mode 100644
index 15ede0d1f..000000000
--- a/_blogposts/archive/2019-04-09-bucklescript-release-5-0-1.mdx
+++ /dev/null
@@ -1,69 +0,0 @@
----
-author: hongbo
-date: "2019-04-09"
-previewImg:
-badge: testing
-title: Announcing BuckleScript 5.0.1
-description: |
----
-
-## Newest Changes
-
-`bs-platform@5.0.1` preview is available, try `npm i -g bs-platform@beta-4.02`!
-A detailed a list of changes is available
-[here](https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#501)
-
-Some notable new features in this release:
-
-### React JSX v3
-
-The new v3 JSX ppx is now available which means zero-cost for react-bindings
-(@rickyvetter will talk about it in a separate post).
-
-### New [@bs.inline] decorator for library authors
-
-Our compilers have a pretty good inlining heuristics by default, in this
-release, we allow some user input for some fine-tuned inlining behavior. Read
-this (https://github.com/BuckleScript/bucklescript/issues/3472) for more use
-cases.
-
-A typical usage is as below
-
-```reason
-module Platform = {
- [@bs.inline] let ios = "ios";
-};
-```
-
-If user wants to write an interface, it has to carry the payload though:
-
-```reason
-module Platform: {
- [@bs.inline "ios"]
- let ios: string;
-} = {
- [@bs.inline]
- let ios = "ios";
-};
-```
-
-It is a bit verbose for library authors, but this should be transparent to
-library users.
-
-
-
-We are also actively working on a new offical release targeted to OCaml 4.06
-for the forthcoming [reason-conf](https://www.reason-conf.com/), below is
- proposed release schedule:
-
-We are going to support OCaml 4.06 and 4.02 at the same time for a while.
-
-The corresponding versions for `bs-platform` would be 5.(targeting 4.02 OCaml)
-and 6. (targeting 4.06).
-
-`5.*` is recommended for production usage, bug fix is prioritized (tagged as
-`beta-4.02` for pre-rleases)
-
-`6.*` is expected to have some issues but encouraged to experiment until we
-make an official announcement it is great for production. (tagged as
-`beta-4.06` for pre-releases)
diff --git a/_blogposts/archive/2019-04-22-bucklescript-release-5-0-4.mdx b/_blogposts/archive/2019-04-22-bucklescript-release-5-0-4.mdx
deleted file mode 100644
index 610e2e038..000000000
--- a/_blogposts/archive/2019-04-22-bucklescript-release-5-0-4.mdx
+++ /dev/null
@@ -1,45 +0,0 @@
----
-author: hongbo
-date: "2019-04-22"
-previewImg:
-title: Architectural Changes in BuckleScript 5.0.4 and 6.0.1
-badge: release
-description: |
----
-
-## Upcoming Changes
-
-We are going to make releases of bs-platform@5.0.4 and bs-platform@6.0.1, this
-release mostly contains bug fixes.
-
-At the same time, we are introducing an internal change which should be fine
-for average users.
-
-If you are tooling authors, here are some details: previously we ship react_jsx
-ppx as a stand-alone binary, for example, reactjs_jsx_ppx_v2.exe,
-reactjs_jsx_ppx_v2.exe. Recently we start more close integration with
-[reason](https://reasonml.github.io), so it is absorbed into bsc.exe itself, we
-introduced a flag to have react-jsx on/off (note these are internal flags, not
-expected to be exposed to average users):
-
-```
-bsc.exe -bs-jsx 2 # turn on reactjs_jsx_ppx_v2
-bsc.exe -bs-jsx 3 # turn on reactjs_jsx_ppx_v3
-```
-
-Like before, we also ship a stand alone bsppx.exe, it now absorbs
-reactjs_jsx_ppx as well.
-
-
-```
-bsppx.exe -bs-jsx 2 # turn on reactjs_jsx_ppx_v2
-bsppx.exe -bs-jsx 3 # turn on reactjs_jsx_ppx_v3
-```
-
-The benefit of this change is that it help reduced the prebuilt binary size
-significantly and it also help shave 5~10ms per file compilation.
-
-Another minor change we added, is that we introduced an env variable
-`BS_VSCODE` to help error messages more adapted to VsCode, see
-[here](https://bucklescript.github.io/docs/en/build-configuration#bs-vscode-error-output-adapted-for-vscode)
-for more details.
diff --git a/_blogposts/archive/2019-05-21-ffi-overview.mdx b/_blogposts/archive/2019-05-21-ffi-overview.mdx
deleted file mode 100644
index 6f6e6e377..000000000
--- a/_blogposts/archive/2019-05-21-ffi-overview.mdx
+++ /dev/null
@@ -1,192 +0,0 @@
----
-author: hongbo
-date: "2019-05-21"
-previewImg:
-title: A High Level Overview of BuckleScript Interop with JS
-description: |
----
-
-## JS Interop in BuckleScript
-
-When users start to use BuckleScript to develop applications targeting JS, they
-have to interop with various APIs provided by the JS platform.
-
-In theory, like [Elm](https://elm-lang.org/), BuckleScript could ship a
-comprehensive library which contains what most people would like to use daily.
-This, however, is particularly challenging, given that JS is running on so many
-platforms for example, [Electron](https://electronjs.org/),
-[Node](https://nodejs.org/) and the Browser, yet each platform is still
-evolving quickly. So we have to provide a mechanism to allow users to bind to
-the native JS API quickly in userland.
-
-There are lots of trade-off when designing such a FFI bridge between OCaml and
-the JavaScript API. Below, we list a few key items which we think have an
-important impact on our design.
-
-## Interop design constraints
-
-### BuckleScript is still OCaml / Reason
-
-We are not inventing a new language. In particular, we can not change the
-concrete syntax of OCaml. Luckily, OCaml introduced
-[attributes](https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec260) and
-[extension nodes](https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec262)
-since 4.02, which allows us to customize the language to a minor extent. To be
-a good citizen in the OCaml community, all attributes introduced by
-BuckleScript are prefixed with `bs`.
-
-### Bare metal efficiency should always be possible for experts in pure OCaml
-
-Efficiency is at the heart of BuckleScript's design philosophy, in terms of
-both compilation speed and runtime performance. While there were other strongly
-typed functional languages running on the JS platform before we made
-BuckleScript, one thing in particular that confused us was that in those
-languages, people have to write `native JS` to gain performance. Our goal is
-that when performance really matters, it is still possible for experts to write
-pure OCaml without digging into `native JS`, so users don't have to make a
-choice between performance and type safety.
-
-## Easy interop using raw JS
-
-BuckleScript allows users to insert raw JS using extension nodes directly.
-Please refer to the
-[documentation](https://bucklescript.github.io/docs/en/embed-raw-javascript)
-for details. Here we only talk about one of the most used styles: inserting raw
- JS code as a function.
-
-```reason
-let getSafe: (array(int), int) => int = [%raw
- (a, b) => {|
- if (b>=0 && b < a.length) {
- return a [b]
- }
- throw new Error("out of range")
- |}
-];
-
-let v = [|1, 2, 3|]->getSafe(-1);
-```
-
-Here the raw extension node asks the user to list the parameters and function
-statement in raw JS syntax. The generated JS code is as follows:
-
-```js
-function getSafe (a,b){
- if (b>=0 && b < a.length) {
- return a [b]
- }
- throw new Error("out of range")
- };
-
-var v = getSafe(/* array */[
- 1,
- 2,
- 3
- ], -1);
-```
-
-Inserting raw JS code as a function has several advantages:
-
-- It is relatively safe; there is no variable name polluting.
-- It is quite expressive since the user can express everything inside the function body.
-- The compiler still has some knowledge about the function, for example, its arity.
-
-Some advice about using this style:
-- Always annotate the raw function with explicit type annotation.
-- When annotating raw JS, you can use polymorphic types, but don’t create them when you don’t really need them. In general, non polymoprhic type is safer and more efficient.
-- Write a unit test for the function.
-
-Note that a nice thing about this mechanism is that no separate JS file is
-needed, so no change to the build system is necessary in most cases. By using
-this mechanism, BuckleScript users can already deal with most bindings.
-
-## Interop via attributes
-
-If you are a developer busy shipping, the mechanism above should cover almost
-everything you need. A minor disadvange of that mechanism is that it comes with
-a cost: a raw function can not be inlined since it is JavaScript, so the
-BuckleScript compiler does not have a deep knowledge about the function.
-
-To demonstrate interop via attributes, we are going to show a small example of
-binding to JS `date`. There are lots of advanced topics in the
-[documentation](https://bucklescript.github.io/docs/en/interop-overview); here
-we are only talking about one of the most-used methods for interop.
-
-The key idea is to bind your JS object as [an abstract data
-type](https://en.wikipedia.org/wiki/Abstract_data_type) where a data type is
-defined by its behavior from the point of view of a user of the data, instead
-of the data type’s concrete representations.
-
-```reason
-type date;
-
-[@bs.new]
-external fromFloat : float => date = "Date" ;
-[@bs.send]
-external getDate : date => float = "getDate" ;
-[@bs.send]
-external setDate : date => float => unit = "setDate";
-
-let date = fromFloat (10000.0);
-date->setDate (3.0);
-let d = date -> getDate;
-```
-
-The preceding code generates the following JS. As you can see, the binding
-itself is zero cost and serves as formal documentation.
-
-```js
-var date = new Date(10000);
-date.setDate(3);
-var d = date.getDate();
-```
-
-A typical workflow is that we create an abstract data type, create bindings for
-a “maker” using `bs.new`, and bind methods using `bs.send`.
-
-Thanks to native support of abstract data types in OCaml, the interop is easy
-to reason about.
-
-Some advice when using this style:
-- Again, you can use polymorphic types in your annotations, but don't create
- polymorphic types when you don't need them.
-- Write a unit test for each external.
-
-As a comparison, we can create the same binding using `raw`:
-
-```reason
-type date;
-let fromFloat: float => date = [%raw d => {|return new Date(d)|}];
-let getDate: date => float = [%raw d => {|return d.getDate()|}];
-let setDate: (date, float) => unit = [%raw
- (d, v) => {|
- d.setDate(v);
- return 0; // ocaml representation of unit
-|}
-];
-
-let date = fromFloat(10000.);
-date->setDate( 3.);
-let d = date->getDate;
-```
-
-The generated JS is as follows, and you can see the cost:
-
-```js
-function fromFloat (d){return new Date(d)};
-
-function getDate (d){return d.getDate()};
-
-function setDate (d,v){
- d.setDate(v);
- return 0; // ocaml representation of unit
-};
-
-var date = fromFloat(10000);
-
-setDate(date, 3);
-
-var d = getDate(date);
-```
-
-
diff --git a/_blogposts/archive/2019-06-26-bucklescript-release-5-0-5.mdx b/_blogposts/archive/2019-06-26-bucklescript-release-5-0-5.mdx
deleted file mode 100644
index 8bb0d8b0c..000000000
--- a/_blogposts/archive/2019-06-26-bucklescript-release-5-0-5.mdx
+++ /dev/null
@@ -1,85 +0,0 @@
----
-author: hongbo
-date: "2019-06-26"
-previewImg:
-badge: release
-title: Announcing BuckleScript 5.0.5 and 6.0.2
-description: |
----
-
-`bs-platform` 5.0.5 (for OCaml 4.02.3) and 6.0.2 (for OCaml 4.06.1) is
-released.
-
-A detailed list of changes is available
-[here](https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#505)
-
-It has some critical bug fixes that we suggest users to upgrade.
-
-Some feature enhancement is described as below:
-
-## User land C stubs polyfill
-
-Previously, for existing OCaml libraries which rely on some C primitives, it
-has to be patched in source level. In this release, user can provide such
-support independently without patching the source code.
-
-Suppose you have a Reason module which relies on an C primitive as below:
-
-```reason
-external ff : (int,int) => int = "caml_fancy_add" ;
-```
-
-`caml_fancy_add` is a C function for native code, now we can provide this
-support in a js files, what user needs to do is adding `caml_fancy_add` to a
-global variable like this
-
-```js
-/**
- * @param {int} x
- * @param {int} y
- * @returns {int}
- *
- */
-require('bs-platform/lib/js/caml_external_polyfill.js').register('caml_fancy_add',function(x,y){
- return + ((""+x ) + (""+y))
-})
-```
-
-Note this is an experimental feature that we don't suggest users to use it
-extensively, it is provided as an escape hatch. We are also expecting feedback
-to see how we could improve it, so there might be some backward incompatible
-changes.
-
-## A new warning number 105
-
-Previously, there are some scenarios that the Js function name is inferred
-during the interop.
-
-For example
-```ocaml
-external f : int -> int = "" [@@bs.val]
-```
-```reason
-[@bs.val] external f : int => int = ""
-```
-Here the JS function name is inferred as `f` which is the same as OCaml
-function name.
-
-Such ffi declaration is fragile to refactoring when changing names of f, it
-will also change the name of js function name which is probably not what user
-expected.
-
-105 warning number is to help warn against this case (turned on by default).
-
-## Simplified debugger mode
-
-Previously, user has to add `-bs-g` flag to `bsc-flags` in `bsconfig.json` and
-add one line code to the main module. Such code change is no longer needed,
-only the flag is needed.
-
-## Build performance improvement
-
-We improved the build performance and simplified the design of the build
-significantly in this release, we will have a separate post about it.
-
-Happy hacking!
diff --git a/_blogposts/archive/2019-08-12-bucklescript-release-5-1-0.mdx b/_blogposts/archive/2019-08-12-bucklescript-release-5-1-0.mdx
deleted file mode 100644
index 432d093b5..000000000
--- a/_blogposts/archive/2019-08-12-bucklescript-release-5-1-0.mdx
+++ /dev/null
@@ -1,139 +0,0 @@
----
-author: hongbo
-date: "2019-08-12"
-previewImg:
-badge: release
-title: Announcing BuckleScript 5.1.0
-description: |
----
-
-## New Release
-
-`bs-platform` 5.1.0 (for OCaml 4.02.3) and 6.1.0 (for OCaml 4.06.1) is ready
-for testing.
-
-You can install it via `npm i -g bs-platform@5.1.0` (or `npm i -g
-bs-platform@6.1.0-dev.6`).
-
-A detailed list of changes is available
-[here](https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#510)
-
-
-Some feature enhancements are described as follows:
-
-## Introducing `bsc` to public
-
-`bsc` is the underlying compiler which is invoked by `bsb`. In this release we
-simplified it a bit so that it can be used directly by customers for simple
-tasks. It is available after you have `bs-platform` installed.
-
-Suppose you have a file called `test.re`:
-
-```reason
-let rec fib = n =>
- switch (n) {
- | 0
- | 1 => 1
- | n => fib(n - 1) + fib(n - 2)
- };
-Js.log(fib(0));
-```
-
-You can compile it directly via `bsc test.re`, producing the following output:
-
-```js
-bucklescript.github.io>bsc test.re
-// Generated by BUCKLESCRIPT, PLEASE EDIT WITH CARE
-'use strict';
-function fib(n) {
- if (n === 0 || n === 1) {
- return 1;
- } else {
- return fib(n - 1 | 0) + fib(n - 2 | 0) | 0;
- }
-}
-console.log(fib(0));
-exports.fib = fib;
-/* Not a pure module */
-```
-
-You can also get the inferred signature directly via `bsc -i test.re`
-
-```reason
-let fib: int => int;
-```
-
-Or even better, you can do a one liner in bsc, via `-e` option.
-
-```
-bucklescript>bsc -i -e 'let id = x => x'
-let id: 'a => 'a;
-```
-
-> **Note:** `bsc` supports vanilla OCaml syntax as well, this is only recommended for
-> toying around, for serious development, `bsb` is recommended.
-
-## `bstracing` to visualize build profile
-
-After you finish the build process, you can run `bstracing` directly. This
-generates a data file called `tracing_${hour}_${minute}_${second}.json ` which
-can be loaded into chrome via `chrome://tracing`.
-
-Below is a profile image that shows the tracing graph for a large project:
-
-
-
-And you can zoom-in to see more details:
-
-
-
-
-## Support of ppx with arguments
-
-We extended the schema to support ppx with arguments:
-
-```json
-{
- "ppx-specs": {
- "type": "array",
- "items": {
- "oneOf" : [
- {
- "type": "string" // single command
- },
- {
- "type" : "array", // command with args
- "items": {
- "type" : "string"
- }
- }
- ]
- }
- }
-}
-```
-
-## Respect `NODE_PATH` when resolving dependent modules
-
-Previously, `bsb` was tied to npm package structures by searching
-`node_modules`. In this release, `bsb` also tries to search paths listed in
-`NODE_PATH` so that `bsb` is no longer tied to the npm or yarn package manager.
-
-## Build performance improvement
-
-Yes, performance is increased with each release!
-
-Quite a lot of work was spent in house-keeping this release. We changed the
-internal data representation to a more compact format. Here is the result of
-using `bstracing` to show a comparison of clean building a large project around
-(2 * 5 * 5 * 5 * 5 = 1250 files):
-
-Version 5.0.6 (around 4.8s)
-
-
-
-Version 5.1.0 (around 4.2s)
-
-
-
-Happy hacking!
diff --git a/_blogposts/archive/2019-09-23-bucklescript-release-5-2-0.mdx b/_blogposts/archive/2019-09-23-bucklescript-release-5-2-0.mdx
deleted file mode 100644
index 8c2355fd6..000000000
--- a/_blogposts/archive/2019-09-23-bucklescript-release-5-2-0.mdx
+++ /dev/null
@@ -1,91 +0,0 @@
----
-author: hongbo
-date: "2019-09-23"
-previewImg:
-badge: release
-title: Announcing BuckleScript 5.2.0 / 6.2.0
-description: |
----
-
-## New Release
-
-`bs-platform` 5.2.0/6.2.0 is released, it contains several major enhancement
-that we would like to share with you.
-
-You can install it via `npm i -g bs-platform@5.2.0`
-
-## Local module compiled into object
-
-OCaml has an [advanced module
-system](https://people.mpi-sws.org/~dreyer/thesis/old/thesis050405.pdf) for
-people to structure large scale applications, it supports first class module
-and higher-order module system which is unique compared to other ML-like
-languages such as F# and Haskell.
-
-In previous versions, BuckleScript compiled local modules into a JS array
-whereby global modules (module produced by a file)were transformed into JS
-objects.
-
-When a local module is compiled into a JS array, the field name is stripped
-away, which makes debugging and JS interop difficult. To make the debugging
-experience better, we instrumented the array with field names in debug mode,
-this mitigated the debugging issue, but still present challenges for JS
-interop.
-
-In this release, the compiler generates uniform representation for global
-module and local module -- idiomatic JS object, this makes OCaml's module
-system more valuable to JS target.
-
-Below is an image showing the diff in this release
-
-
-
-As you can see, the `id` module changed from an array into an JS object.
-
-## Pattern match code generation with annotations
-
-BuckleScript aims to generate readable code.
-
-OCaml has a sophiscated pattern match compiler, it generates well optimized
-code, however, for complex pattern matching, the constructor name is lost on
-native backend, this is also one of the very few case where we generate magic
-number in JS backend, this makes debugging particularly challenging for large
-complex pattern match.
-
-In this release, we made such information available to JS backend so that we
-annotate the generated JS code with its names.
-
-Below is an image showing the diff in this release
-
-
-
-In the future, we will explore if we can produce such annotation in the runtime without losing efficiency.
-
-## Code generation improvement in various places
-
-We care about the generated code quality, and will always keep improving it
-regardless how good it is.
-
-In this release, we improved the code generation in quite a lot of places
-including lazy evaluation, if branches and pattern match.
-
-In particular, we added a data-flow pass to eliminate non-necessary staticfail
-case.
-
-
-
-## Important bug fixes
-
-This release also comes with a couple of important bug fixes, in particular,
-#3805 the stale build issue and #3823 the interaction with reason langauge
-service.
-
-## Upcoming breaking changes
-
-In next release, we plan to [remove deprecated
-getters](https://reasonml.chat/t/ann-remove-deprecated-getters-in-deriving-abstract-after-5-2-0/1908).
-
-A detailed list of changes is available
-[here](https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#520)
-
-Happy hacking!
diff --git a/_blogposts/archive/2019-10-16-another-encoding.mdx b/_blogposts/archive/2019-10-16-another-encoding.mdx
deleted file mode 100644
index 900069c13..000000000
--- a/_blogposts/archive/2019-10-16-another-encoding.mdx
+++ /dev/null
@@ -1,194 +0,0 @@
----
-author: hongbo
-date: "2019-10-16"
-previewImg:
-title: Another way of encoding type identity for BuckleScript libraries without using big functor
-description: |
----
-
-Note this article is for library authors, it has something in depth which is
-not necessary for people who use BuckleScript at daily work.
-
-When we build some generic data structure, abstract over function is not
-enough. For example, a type safe generic balanced AVL tree not only relies on
-the types of a comparison function, but also the identity of such function. Two
-balanced AVL trees which are initialized over same type of comparison function
-still can not be mixed.
-
-```reason
-module Eq1 = {
- let eq = (x, y) => x == y;
-};
-
-module Eq2 = {
- let eq = (x, y) => x == y;
-};
-```
-
-Take the two modules above for example, they have the same type, but we need a
-way to mark their identity so that data structures instantiated using them can
-not be mixed.
-
-A traditional way is using functor:
-
-```reason
-module Make = (
- Cmp: {
- type t;
- let eq: (t, t) => bool;
- }) : {
- type key = Cmp.t;
- type coll;
- let empty: coll;
- let add: (coll, key) => coll;
-} => {
- open Cmp;
- type key = t;
- type coll = list(key);
- let empty = [];
- let add = (y: coll, e: key) =>
- if (List.exists(x => eq(x, e), y)) {
- y;
- } else {
- [e, ...y];
- };
-};
-
-module Ins1 = Make({
- type t = int;
- let eq = (x, y) => x == y;
-});
-
-module Ins2 = Make({
- type t = int;
- let eq = (x, y) => x * x == y * y;
-});
-```
-
-By marking `coll` as abstract type, when such functor is
-initialized,`Ins1.coll` and `Ins2.coll` are no longer the same.
-
-```reason
-let v = [Ins1.empty, Ins2.empty];
-```
-
-When mixing them together, we get a type error
-
-```
-File ..., line 31, characters 21-31:
-Error: This expression has type Ins2.coll
- but an expression was expected of type Ins1.coll
-```
-
-There are some issues with such encoding:
-
-- From runtime point of view, `Ins1` is initialized during runtime, its
- implementation is a *big closure*, which means even if you only use on
- function in `Ins1` module, all functions will be linked in.
-
-- From user point of view, people has to call `Ins1.add` and `Ins2.add` instead
- of calling `Ins.add`, this makes code less polymorphic.
-
-Now we introduce another encoding, note it is quite sophiscated that is
-recommended only for library authors
-
-```reason
-module Cmp: {
- type cmp('a, 'id);
- let eq: (cmp('a, 'id), 'a, 'a) => bool;
- module Make: (
- M: {
- type t;
- let eq: (t, t) => bool;
- }
- ) => {
- type identity;
- let eq: cmp(M.t, identity);
- };
-} = {
- type cmp('a, 'id) = ('a, 'a) => bool;
- module Make = (
- M: {
- type t;
- let eq: (t, t) => bool;
- }
- ) => {
- type identity;
- include M;
- };
- let eq = (cmp, x, y) => cmp(x, y); /* This could be inlined by using externals */
-};
-
-open Cmp;
-
-module Coll: {
- type coll('k, 'id);
- let empty: cmp('k, 'id) => coll('k, 'id);
- let add: (coll('k, 'id), 'k) => coll('k, 'id);
-} = {
- type coll('k, 'id) = {
- eq: cmp('k, 'id),
- data: list('k),
- };
-
- let empty = (type t, type identity, eq: cmp(t, identity)) => {
- data: [],
- eq,
- };
- let add = (x: coll('k, 'id), y: 'k) =>
- if (List.exists(a => Cmp.eq(x.eq, a, y), x.data)) {
- x;
- } else {
- {
- data: [y, ...x.data],
- eq: x.eq,
- };
- };
-};
-```
-
-The key is the construction of Cmp modules, we create an abstract type `cmp`
-which is signed by a phantom type as its identity, it is unique whenever user
-create it by calling `Make` functor. Here we are still using functor, but it is
-small functor.
-
-The usage is as below:
-
-```reason
-module S0 = Make({
- type t = int;
- let eq = (x, y) => x == y;
-});
-
-module S1 = Make({
- type t = int;
- let eq = (x, y) => x * x == y * y;
-});
-
-let v0 = Coll.empty(S0.eq);
-let v1 = Coll.empty(S1.eq);
-
-let a0 = Coll.add(v0, 1);
-let a1 = Coll.add(v1, 1);
-```
-
-In practice, we can make use of first class modules to get rid of functors from
-end users, which is saved for readers.
-
-When we mix `a0` and `a1`, we will get a type error
-
-```
-File ..., line 71, characters 13-15:
-Error: This expression has type (int, S1.identity) Coll.coll
- but an expression was expected of type (int, S0.identity) Coll.coll
- Type S1.identity is not compatible with type S0.identity
-```
-
-As you read here, by using such encoding, the data structure is more
-generalized from user point of view. The generated JS code is not in a big
-closure so that it can be dead code eliminated better.
-
-This style is extensively used in Belt encoding, we encourage you to have a
-look at its implementation for better ideas.
-
-
diff --git a/_blogposts/archive/2019-11-18-whats-new-in-7-pt1.mdx b/_blogposts/archive/2019-11-18-whats-new-in-7-pt1.mdx
deleted file mode 100644
index b13ad7b60..000000000
--- a/_blogposts/archive/2019-11-18-whats-new-in-7-pt1.mdx
+++ /dev/null
@@ -1,67 +0,0 @@
----
-author: hongbo
-date: "2019-11-18"
-previewImg:
-badge: testing
-title: What's new in BuckleScript v7 (Part 1)
-description: |
----
-
-## New major dev release available
-
-The new major version of BuckleScript is coming
--[7.0.0-dev.1](https://github.com/BuckleScript/bucklescript/pull/3968) is now
-released for testing!
-
-We are maintaining `5.*` and `6.*` for OCaml `4.02` and `4.06` for a while,
-since this release we are moving forward and focusing on release 7.* (for OCaml
-4.06).
-
-This is a major release comes with lots of nice features listed
-[here](https://github.com/BuckleScript/bucklescript/blob/master/Changes.md).
-
-We talk about some highlights here
-
-- refmt upgraded to latest, it comes with better error message
-
-- OCaml Records compiled into JS objects
-
-This is one of the most desired features, it is finally landed.
-
-See the generated code below for excitement!
-
-```reason
-type t = {
- x: int,
- y: int,
- z: int,
-};
-
-let obj = {x: 3, y: 2, z: 2};
-
-let obj2 = {...obj, y: 4};
-```
-
-```js
-var obj2 = {
- x: 3,
- y: 4,
- z: 2
-};
-
-var obj = {
- x: 3,
- y: 2,
- z: 2
-};
-```
-
-This new change makes record much more useful and its interaction with
-`private` type; unboxed option type will make interop with JS much nicer!
-
-As always, we continue improving our optimizer in various
-[commits](https://github.com/BuckleScript/bucklescript/pull/3966/files?file-filters%5B%5D=.js),
-we belive that not only a better language but also an implementation of high
-quality is key to push typed functional programming into industry.
-
-Happy hacking!
diff --git a/_blogposts/archive/2019-11-28-whats-new-in-7-pt2.mdx b/_blogposts/archive/2019-11-28-whats-new-in-7-pt2.mdx
deleted file mode 100644
index b4e8dae10..000000000
--- a/_blogposts/archive/2019-11-28-whats-new-in-7-pt2.mdx
+++ /dev/null
@@ -1,49 +0,0 @@
----
-author: hongbo
-date: "2019-11-28"
-previewImg:
-badge: testing
-title: What's new in BuckleScript v7 (Part 2)
-description: |
----
-
-## New `dev` Release
-
-The second dev release
-[7.0.0-dev.2](https://github.com/BuckleScript/bucklescript/pull/3995) is
-released for testing!
-
-As we mentioned in the [previous
-post](https://bucklescript.github.io/blog/2019/11/18/whats-new-in-7), we
-compile records into js objects in this release. This makes the generated code
-more idiomatic, however, this is not enough to write idiomatic bindings to
-manipulate arbitrary js objects, since the key of js objects can be arbitrary
-which is not expressible in ReasonML syntax, so we support user level
-customization now, which makes idiomatic bindings really easy.
-
-```reason
-type entry = {
- [@bs.as "EXACT_MAPPING_TO_JS_LABEL"]
- x: int,
- [@bs.as "EXACT_2"]
- y: int,
- z: obj,
-}
-and obj = {
- [@bs.as "hello"]
- hi: int,
-};
-
-let f4 = ({x, y, z: {hi}}) => (x + y + hi) * 2;
-```
-
-```js
-function f4(param) {
- return (((param.EXACT_MAPPING_TO_JS_LABEL + param.EXACT_2 | 0) + param.z.hello | 0) << 1);
-}
-```
-
-As you can see, you can manipulate js objects using Reason pattern match syntax, the generated
-code is highly efficient, more importantly, bindings to JS will be significantly simplifie.
-
-Happy Hacking.
diff --git a/_blogposts/archive/2019-12-20-bucklescript-release-7-0-2.mdx b/_blogposts/archive/2019-12-20-bucklescript-release-7-0-2.mdx
deleted file mode 100644
index a5e280e15..000000000
--- a/_blogposts/archive/2019-12-20-bucklescript-release-7-0-2.mdx
+++ /dev/null
@@ -1,176 +0,0 @@
----
-author: hongbo
-date: "2019-12-20"
-previewImg:
-badge: release
-title: Announcing BuckleScript 7.0.2-dev.1
-description: |
----
-
-## Happy Holiday Release!
-
-[bs-platform@7.0.2-dev.1](https://github.com/BuckleScript/bucklescript/pull/4062)
-is released for testing!
-
-Try it via
-
-```
-npm i -g bs-platform@7.0.2-dev.1
-```
-
-This release contains several bug fixes for
-[refmt](https://github.com/facebook/reason)(updated from 3.5.1 to 3.5.4). We
-also spent quite some time improving the compiler performance. For example, we
-optimized our specialized hash based data structures, which means that we can
-expect a 5% better build time performance. We would like to collect more
-benchmark data, so we are happy for any feedback / benchmarks from our
-community!
-
-A highlighting feature is that we added Generalized Unboxed Support (so called
-[@unboxed] annotations). Here's a short definition from the official OCaml
-Manual:
-
-
-> unboxed can be used on a type definition if the type is a single-field record
-> or a concrete type with a single constructor that has a single argument. It
-> tells the compiler to optimize the representation of the type by removing the
-> block that represents the record or the constructor (i.e. a value of this type
-> is physically equal to its argument). In the case of GADTs, an additional
-> restriction applies: the argument must not be an existential variable,
-> represented by an existential type variable, or an abstract type constructor
-> applied to an existential type variable.
-
-
-**Note**: The beforementioned restriction about GADTs only applies to OCaml's
-native compiler, not to BuckleScript's JavaScript compilation. So we will get
-the maximum value with less confusing error messages!
-
-The exciting thing about this feature is that we will now have more ways of
-expressing our programs in our typical type safe records and variants without
-sacrificing on runtime performance ("zero cost interop").
-
-The best way to understand this feature is by looking at the following
-examples:
-
-**Unboxed variants:**
-
-```reason
-[@unboxed]
-type t = A(int);
-let x = A(3);
-```
-
-will translate to following JS:
-
-```js
-var x = 3;
-```
-
-As you can see, we are "unboxing" the `int` value from the internal variant
-representation, so the variant will get completely invisible to the runtime.
-Great for e.g. mapping to stringly typed JavaScript enums!
-
-**Unboxed Records (1 field only)**
-
-```reason
-[@unboxed]
-type t2 = {f: string};
-let x = {f: "foo"};
-```
-
-will translate to following JS:
-
-```js
-var x = "foo";
-```
-
-The same principle as with variants. Now a lot of people will probably ask:
-"Why would I ever want a 1 field record?". There are multiple reasons, one of
-them would be a `ref` type, which is just a syntax sugar for a `{ contents:
-'a}` record.
-
-Another use case is for expressing high rank polymorphism without cost:
-
-```reason
-[@unboxed]
-type r = {f: 'a. 'a => 'a};
-let map_pair = (r, (p1, p2)) => (r.f(p1), r.f(p2));
-```
-
-**Note:** `'a. 'a => 'a` describes a polymorphic function interface, where `'a`
-can be called with many different types (e.g. `f(1)` and `f("hi")`). The
-compiler will not try to lock `'a` for the first type it sees (e.g. the `int`)
-on the first call site. The parameter `'a` is therefore polymorphic!
-
-By `unboxing` those records with one polymorphic function, we will get rid of
-[value restriction for our existing encoding of uncurried
-function](https://github.com/BuckleScript/bucklescript/issues/4058), this will
-be a major feature!
-
-**Unboxed GADTs:**
-
-Since GADTs are lesser known in Reason syntax, we also added some OCaml snippet
-to get a better idea of how the example data structure is defined.
-
-```reason
-[@unboxed]
-type t =
- | Any ('a) : t;
-
-let array = [|Any(3), Any("a")|];
-```
-```ocaml
-(* OCaml *)
-type t =
- | Any : 'a -> t
-[@@unboxed]
-
-let array = [|Any 3; Any "a"|]
-```
-
-The examples above will translate to following JS:
-
-```js
-var array = [ 3, "a"];
-```
-
-As you can already tell, this feature will give us way better possibilities to
-do interop with polymorphic array representations in JavaScript (without losing
- any type safetiness!).
-
-As a more concrete use-case, this will give users the possibility to define
-types such as `int_or_string`.
-
-**Note:** Even if this GADT `t` contains an ADT `Any`, it doesn't mean that
-it's the same as `any` in TypeScript. An `Any` value is constrained to a
-certain contract (`'a -> t`), the array `[|Any(3), Any("a")|]` is inferred as a
-`array(t)`. When users try to use `Any` values, they need to unpack them,
-process the value inside, and repack them again. Pretty neat, right?
-
-### Conclusion
-
-This release will introduce the `[@unbox]` annotation to give us better ways to
-do zero cost interop with variants, records, higher kinded polymorphic
-functions, and GADTs. Under the hood improvements will give us better
-performance as well!
-
-We are really excited about these changes, and we hope so are you. Please check
-out our newest `bs-platform@7.0.2-dev.1` release and let us know if you find
-any issues!
-
-A detailed list of changes is available here:
-https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#702
-
-Happy hacking!
-
-### Appendix
-
-**A sophiscated explanation on why `unboxed` lifts some OCaml's type system
-limitations**
-
-> structural types (objects, classes, polymorphic variants, functions, etc) in
-> OCaml are regular types, ocaml always do the expansion when dealing with such
-> types, there is some limitations for such structural types, for example, non
-> regular definitions are not allowed. Non structural types (variants, records)
-> does not have such limitations, with `unboxed`, we can use non structural
-> types as an indirection without changing its runtime representations.
diff --git a/_blogposts/archive/2020-02-04-bucklescript-release-7-1-0.mdx b/_blogposts/archive/2020-02-04-bucklescript-release-7-1-0.mdx
deleted file mode 100644
index eb34a129c..000000000
--- a/_blogposts/archive/2020-02-04-bucklescript-release-7-1-0.mdx
+++ /dev/null
@@ -1,116 +0,0 @@
----
-author: hongbo
-date: "2020-02-04"
-previewImg:
-tags:
- - Release
-title: Announcing BuckleScript 7.1.0
-description: |
----
-
-## About this Release
-
-`bs-platform@7.1.0` is a major release. You can try it with `npm i -g
-bs-platform`! (If you have permission issues, try `sudo npm i --unsafe-perm -g
-bs-platform`)
-
-It was called 7.0.2 but bumped into 7.1.0 due to a soundness fix (a breaking
-change) as follows:
-
-Previously, the empty array `[||]` was polymorphic. This happens to be true,
-since in native an array is not resizable, so users cannot do anything with it.
-But in JS, we introduced a binding for `push` which can change the size of an
-array dynamically. In this case, an empty array cannot be polymorphic any more.
-
-Removing `push` is possible, but it makes arrays in JS context less useful. To
-fix this issue while keeping `push`, we make `[||]` weakly typed so that its
-type inference is deferred until the first time it is used. If it is never used
-across the module, it has to be annotated with a concrete type; otherwise, the
-type checker will complain.
-
-Several highlighted features are listed as follows:
-
-## Raw JavaScript Parsing/Checking
-
-BuckleScript allows users to embed raw JavaScript code as an escape hatch; it
-used to treat such piece of code as a black box.
-
-In this release we vendor a JavaScript parser (thanks to
-[flowtype](https://github.com/facebook/flow)) for syntax checking and simple
-semantics analysis over `raw`. This is on-going work, but it is already useful
-now.
-
-First, we now report syntax errors properly for `raw`.
-
-Second, for simple semantics analysis, we can tell whether the code inside raw
-is a function or not and the arity of raw function:
-
-```ocaml
-let f = [%raw "function(x){return x}"]
-```
-```reason
-let f = [%raw "function(x){return x}"];
-```
-
-Now we know `f` is a function declaration with no side effect; it can be
-removed by the dead code analyzer if not used. We also know its arity so that
-when it's called we know whether it's fully applied or not.
-
-Because this sort of information can be derived from `raw` directly, the
-special `raw` form we introduced as follows is no longer needed:
-
-```ocaml
-let f = fun%raw x -> {|x|}
-```
-
-```reason
-let f = [%raw x => {|x|}];
-```
-
-To reduce interop API surface, this feature will now be discouraged.
-
-We're also exploring using such knowledge on JS literals and regexes checking.
-
-## Unboxed Types
-
-One major feature introduced in this release is **unboxed types** which is
-blogged [here](https://bucklescript.github.io/blog/2019/12/20/release-7-02).
-
-## Uniform Warning System
-
-Previously warnings are reported in two ways:
-- The OCaml compiler style: `-w +10`
-- Ad-hoc warnings introduced by flags `-bs-warn-unimplemented-external`
-
-
-In this release, we make such integration so that BuckleScript warnings are
-handled in the same way as OCaml's own warnings, for example, the warning
-attribute below can also turn off BuckleScript warnings now.
-
-```reason
-[@warning "-101"]; // file-level config
-```
-
-Based on this effort, we have changed all BuckleScript warnings into OCaml
-style warnings to reduce user-level complexity.
-
-The newly introduced warnings are listed via `bsc -warn-help`:
-
-```
-101 BuckleScript warning: Unused bs attributes
-102 BuckleScript warning: polymorphic comparison introduced (maybe unsafe)
-103 BuckleScript warning: about fragile FFI definitions
-104 BuckleScript warning: bs.deriving warning with customized message
-105 BuckleScript warning: the external name is inferred from val name is unsafe from refactoring when changing value name
-106 BuckleScript warning: Unimplemented primitive used:
-107 BuckleScript warning: Integer literal exceeds the range of representable integers of type int
-108 BuckleScript warning: Uninterpreted delimiters (for unicode)
-```
-
-We also recommend users to turn on `warnerror` and only disable warnings for
-some specific files.
-
-We've also upgraded the Reason parser `refmt` to 3.6.0.
-
-A full list of changes is available here:
-https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#702
diff --git a/_blogposts/archive/2020-02-07-union-types-in-bucklescript.mdx b/_blogposts/archive/2020-02-07-union-types-in-bucklescript.mdx
deleted file mode 100644
index defdf25df..000000000
--- a/_blogposts/archive/2020-02-07-union-types-in-bucklescript.mdx
+++ /dev/null
@@ -1,188 +0,0 @@
----
-author: hongbo
-date: "2020-02-07"
-previewImg:
-title: Union types in BuckleScript
-description: |
- In our our 7.1.0 release we introduced the new [@unboxed] feature for better
- zero-cost interop with GADTs, Variants and single field records. Let's find
- out how this will help us expressing Union types with seamless interop!
----
-
-## Introduction to Union Types
-
-[Union
-types](https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types)
-describe a value that can be one of several types. In JS, it is common to use
-the vertical bar (|) to separate each type, so `number | string | boolean` is
-the type of a value that can be a number, a string, or a boolean.
-
-
-Following [the last
-post](https://bucklescript.github.io/blog/2019/12/20/release-7-02) since the
-introduction of unboxed attributes in `7.1.0`, we can create such types as
-follows:
-
-```ocaml
-type t =
- | Any : 'a -> t
-[@@unboxed]
-let a (v : a) = Any v
-let b (v : b) = Any v
-let c (v : c) = Any v
-```
-```reason
-[@unboxed]
-type t =
- | Any('a): t;
-let a = (v: a) => Any(v);
-let b = (v: b) => Any(v);
-let c = (v: c) => Any(v);
-```
-> **Note:** due to the `unboxed` attribute, `Any a` shares the same runtime
-> representation as `a`; however, we need to make sure that user can only
-> construct values of type `a`, `b` , or `c` into type `t`. By making use of the
-> module system, we can achieve this:
-
-```ocaml
-module A_b_c : sig
- type t
- val a : a -> t
- val b : b -> t
- val c : c -> t
-end= struct
-type t =
- | Any : 'a -> t
-[@@unboxed]
-let a (v : a) = Any v
-let b (v : b) = Any v
-let c (v : c) = Any v
-end
-```
-
-```reason
-module A_b_c: {
- type t;
- let a: a => t;
- let b: b => t;
- let c: c => t;
-} = {
- [@unboxed]
- type t =
- | Any('a): t;
- let a = (v: a) => Any(v);
- let b = (v: b) => Any(v);
- let c = (v: c) => Any(v);
-};
-```
-
-What happens when we need to know specifically whether we have a value of type `a`? This is a case by case issue; it depends on whether there are some intersections in the runtime encoding of `a`, `b` or `c`. For some primitive types, it is easy enough to use `Js.typeof` to tell the difference between, e.g, `number` and `string`.
-
-Like [type guards in typescript](https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types), we have to trust the user knowledge to differentiate between union types. However, such user level knowledge is isolated in a single module so that we can reason about its correctness locally.
-
-Let's have a simple example, `number_or_string` first:
-
-```ocaml
-module Number_or_string : sig
- type t
- type case =
- | Number of float
- | String of string
- val number : float -> t
- val string : string -> t
- val classify : t -> case
-end = struct
- type t =
- | Any : 'a -> t
- [@@unboxed]
- type case =
- | Number of float
- | String of string
- let number (v : float) = Any v
- let string (v : string) = Any v
- let classify (Any v : t) : case =
- if Js.typeof v = "number" then Number (Obj.magic v : float)
- else String (Obj.magic v : string)
-end
-```
-```reason
-module Number_or_string: {
- type t;
- type case =
- | Number(float)
- | String(string);
- let number: float => t;
- let string: string => t;
- let classify: t => case;
-} = {
- [@unboxed]
- type t =
- | Any('a): t;
- type case =
- | Number(float)
- | String(string);
- let number = (v: float) => Any(v);
- let string = (v: string) => Any(v);
- let classify = (Any(v): t): case =>
- if (Js.typeof(v) == "number") {
- Number(Obj.magic(v): float);
- } else {
- String(Obj.magic(v): string);
- };
-};
-```
-Note that here we use `Obj.magic` to do an unsafe type cast which relies on `Js.typeof`. In practice, people may use `instanceof`; the following is an imaginary example:
-
-```ocaml
-module A_or_b : sig
- type t
- val a : a -> t
- val b : b -> t
- type case =
- | A of a
- | B of b
- val classify : t -> case
-end = struct
- type t =
- | Any : 'a -> t
- [@@unboxed]
- type case =
- | A of a
- | B of b
- let a (v : a) = Any v
- let b = (v : b) = Any v
- let classify ( Any v : t) =
- if [%raw{|function (a) { return a instanceof globalThis.A}|}] v then A (Obj.magic v : a)
- else B (Obj.magic b)
-end
-```
-```reason
-module A_or_b: {
- type t;
- let a: a => t;
- let b: b => t;
- type case =
- | A(a)
- | B(b);
- let classify: t => case;
-} = {
- [@unboxed]
- type t =
- | Any('a): t;
- type case =
- | A(a)
- | B(b);
- let a = (v: a) => Any(v);
- let b = (v: b) => Any(v);
- let classify = (Any (v): t) =>
- if ([%raw {|function (a) { return a instanceof globalThis.A}|}](v)) {
- A(Obj.magic(v): a);
- } else {
- B(Obj.magic(b));
- };
-};
-```
-Here we suppose `a` is of JS class type `A`, and we use `instanceof` to test it. Note we use some `unsafe` code locally, but as long as such code is carefully reviewed, it has a safe boundary at the module level.
-
-
-To conclude: thanks to `unboxed` attributes and the module language, we introduce a systematic way to convert values from `union types` (untagged union types) to `algebraic data types` (tagged union types). This sort of conversion relies on user level knowledge and has to be reviewed carefully. For some cases where `classify` is not needed, it can be done in a completely type safe way.
diff --git a/_blogposts/archive/2020-02-20-loading-stdlib-in-memory.mdx b/_blogposts/archive/2020-02-20-loading-stdlib-in-memory.mdx
deleted file mode 100644
index 458380c02..000000000
--- a/_blogposts/archive/2020-02-20-loading-stdlib-in-memory.mdx
+++ /dev/null
@@ -1,130 +0,0 @@
----
-author: hongbo
-date: "2020-02-20"
-previewImg:
-title: Improving the Stdlib Loading mechanism
-description: |
- We want to give you some insights on how we will improve the way BuckleScript
- compiles and handles its stdlib modules.
----
-
-## Loading stdlib from memory
-
-
-
-In the next release, we are going to load stdlib from memory instead of from
-external files, which will make the BuckleScript toolchain more accessible and
-performant.
-
-You can try it via `npm i bs-platform@7.2.0-dev.4`
-
-## How does it work
-
-When the compiler compiles a module `test.ml`, the module `Test` will import
-some modules from stdlib. This is inevitable since even basic operators in
-BuckleScript, for example `(+)`, are defined in the Pervasives module, which is
-part of the stdlib.
-
-Traditionally, the compiler will consult `Pervasives.cmi`, which is a binary
-artifact describing the interface of the Pervasives module and
-`Pervasives.cmj`, which is a binary artifact describing the implementation of
-the Pervasives module. `Pervasives.cm[ij]` and other modules in stdlib are
-shipped together with the compiler.
-
-
-**This traditional mode has some consequences:**
-
-- The compiler is not stand-alone and relocatable. Even if we have the compiler
-prebuilt for different platforms, we still have to compile stdlib
-post-installation. `postinstall` is supported by npm, but it has
-[various](https://github.com/BuckleScript/bucklescript/issues/3213)
-[issues](https://github.com/BuckleScript/bucklescript/issues/2799)
-[against](https://github.com/BuckleScript/bucklescript/issues/3254) yarn.
-
-- It's hard to split the compiler from the generated stdlib JS artifacts. When
-a BuckleScript user deploys apps depending on BuckleScript, in theory, the app
-only needs to deploy those generated JS artifacts; the native binary is not
-needed in production. However, the artifacts are still loaded since they are
-bundled together. Allowing easy delivery of compiled code is one of the
-community’s most desired [feature
-requests](https://github.com/BuckleScript/bucklescript/issues/2772).
-
-
-In this release, we solve the problem by embedding the binary artifacts into
-the compiler directly and loading it on demand.
-
-To make this possible, we try to make the binary data platform agnostic and as
-compact as possible to avoid size bloating. The entrance of loading cmi/cmj has
-to be adapted to this new way.
-
-So whenever the compiler tries to load a module from stdlib, it will consult a
-lazy data structure in the compiler itself instead of consulting an external
-file system.
-
-## What are the benefits?
-
-
-
-### More accessiblity.
-
-Package installation now becomes downloading for prebuilt platforms. In the
-future, we can make it installable from a system package manager as well. The
-subtle interaction with [yarn
-reinstall](https://github.com/BuckleScript/bucklescript/issues/2799) is also
-solved once and for all.
-
-
-
-### Easy separation between compiler and JS artifacts
-
-The compiler is just one relocatable file. This makes the separation between
-the compiler and generated JS artifacts easier. The remaining work is mostly to
-design a convention between compiler and stdlib version schemes.
-
-### Better compilation performance
-
-A large set of files is not loaded from the file system but rather from memory
-now!
-
-### Fast installation and reinstallation.
-
-Depending on your network speed, the installation is reduced from 15
-seconds to 3 seconds. Reinstallation is almost a no-op now.
-
-
-
-
-
-### JS playground is easier to build
-
-We translate the compiler into JS so that
-developers can play with it in the browser. To make this happen, we used to
-fake the IO system; this not needed any more since no IO happens when compiling
-a single file to a string.
-
-## Some internal changes
-
-To make this happen, the layout of binaries has been changed to the following
-structure. It is **not recommended** that users depend on the layout, but [it
-happens](https://github.com/BuckleScript/bucklescript/pull/4170#issuecomment-586959464).
-Here is the new layout:
-
-```
-|-- bsb // node wrapper of bsb.exe
-|-- bsc // node wrapper of bsc.exe
-|
-|-- win32
-| |-- bsb.exe
-| |-- bsc.exe
-|
-|---darwin
-| |-- bsb.exe
-| |-- bsc.exe
-|
-|---linux
-| |-- bsb.exe
-| |-- bsc.exe
-
-```
-
-
diff --git a/_blogposts/archive/2020-03-12-bucklescript-release-7-2.mdx b/_blogposts/archive/2020-03-12-bucklescript-release-7-2.mdx
deleted file mode 100644
index c5a3c4f4f..000000000
--- a/_blogposts/archive/2020-03-12-bucklescript-release-7-2.mdx
+++ /dev/null
@@ -1,115 +0,0 @@
----
-author: hongbo
-date: "2020-03-12"
-previewImg:
-tags:
- - Release
-title: Announcing BuckleScript 7.2
-description: |
- This release will give us some small quality of life improvements for tool
- builders, better performance, and a new let %private modifier for hiding
- module functionality.
----
-
-## About the Release
-
-Today we are proud to release `bs-platform 7.2`!
-
-For those unfamiliar with bs-platform, it is the platform for compiling
-[ReasonML](https://reasonml.github.io/) and [OCaml](https://ocaml.org/) to fast
-and readable JavaScript.
-
-You can try it with `npm i bs-platform`!
-
-## Features
-
-### In memory loading stdlib
-
-Since this release, the binary artifacts generated by the stdlib are loaded
-from memory instead of an external file systems, which means much faster
-compilation and installation.
-
-Previously we recommended installing `bs-platform` globally to save on
-installation time.
-
-However, with this release the installation is so fast that we recommend
-installing it locally instead - per project - instead, as there's no additional
-cost, and it provides better isolation.
-
-You can use it with a nice tool called
-[npx](https://www.npmjs.com/package/npx), for example, `npx bsb`.
-
-The installation is also compatible with `--ignore-scripts` for major platforms
-(see [Richard Feldman's talk](https://youtu.be/okrB3aJtUaw?t=921) on the
-security implications), and is more stable with
-[yarn](https://github.com/yarnpkg/yarn)
-
-More technical details can be found in this
-[post](https://bucklescript.github.io/blog/2020/02/20/loading-stdlib-in-memory).
-
-### let %private
-
-In OCaml's module system, everything is public by default, the only way to hide some values is by providing a separate signature to list public fields and their types:
-
-```reason
-module A : { let b : int} = {
- let a = 3 ;
- let b = 4 ;
-}
-
-```
-`let` `%private` gives you an option to mark private fields directly
-
-```reason
-module A = {
- let%private a = 3;
- let b = 4;
-}
-```
-
-`let%private` also applies to file level modules, so in some cases, user does not need to provide a separate interface file just to hide some particular values.
-
-Note interface files are still recommended as a general best practice since they give you better separate compilation units and also they're better for documentation. Still, `let%private` is useful in the following scenarios:
-
-- Code generators. Some code generators want to hide some values but it is sometimes very hard or time consuming for code generators to synthesize the types for public fields.
-
-- Quick prototyping. During prototyping, we still want to hide some values, but the interface file is not stable yet, `let%private` provide you such convenience.
-
-
-### Int64 performance optimization
-
-We received feedback from some users that various Int64 operations became bottlenecks in their code performance, in particular `Int64.to_string`.
-
-We responded to this, and after some hard work - but _without_ changing the underlying representation - our `Int64.to_string` is even faster than `bigint` for common inputs.
-
-A micro-benchmark for comparison:
-```
-running on 7.1
-Int64.to_string: 367.788ms # super positive number
-Int64.to_string: 140.451ms # median number
-Int64.to_string: 375.471ms # super negative number
-
-bigint
-Int64.to_string: 25.151ms
-Int64.to_string: 12.278ms
-Int64.to_string: 21.011ms
-
-latest
-Int64.to_string: 43.228ms
-Int64.to_string: 5.764ms
-Int64.to_string: 43.270ms
-```
-
-We also apply such optimizations to other Int64 operations.
-
-Note that Int64 is implemented in OCaml itself without any raw JavaScript. This is case compelling hints that our optimizing compiler not only provides expressivity and type-safe guarantees, but also empowers users to write maintainable, *efficient* code.
-
-## File level compilation flags
-
-In this release, we also provide a handy flag to allow users to override some configurations at the file level.
-
-```reason
-[@bs.config {flags: [|"-w", "a", "-bs-no-bin-annot"|]}]; // toplevel attributes
-```
-
-A full list of changes is available here: https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#72
diff --git a/_blogposts/archive/2020-03-26-generalize-uncurry.mdx b/_blogposts/archive/2020-03-26-generalize-uncurry.mdx
deleted file mode 100644
index ff35f0321..000000000
--- a/_blogposts/archive/2020-03-26-generalize-uncurry.mdx
+++ /dev/null
@@ -1,139 +0,0 @@
----
-author: hongbo
-date: "2020-03-26"
-previewImg:
-title: Generalized Uncurry Support in 7.3
-description: |
----
-
-## Introduction
-
-[ReasonML](https://github.com/facebook/reason) is a
-[curried](https://en.wikipedia.org/wiki/Currying) language, while Js is an
-uncurried language. When compiling ReasonML into Js, there's lots of headache
-due to the semantics mismatch.
-
-After several years of research and development, we will finally reach a new
-milestone in our next release: adding a lightweight uncurried calling
-convention to ReasonML.
-
-## Why we need native uncurried calling convention
-
-**The curried call is inherently slower than the uncurried call.**
-
-A native implementation of curried call like [purescript](https://www.purescript.org/) does will generate very slow code:
-
-```js
-let curriedFunction = x => y => z => x + y +z ;
-let curriedApply = curriedFunction(1)(2)(3); // memory allocation triggered
-```
-
-BuckleScript does tons of optimizations and very aggressive arity inference so that the curried function is compiled into a multiple-arity function, and when the application is supplied with the exact arguments -- which is true in most cases, it is applied like normal functions.
-
-However, such optimization does not apply to high order functions:
-
-```reason
-let highOrder = (f,a,b)=> f (a, b)
-// can not infer the arity of `f` since we know
-// nothing about the arity of `f`, unless
-// we do the whole program optimization
-```
-
-In cases where arity inference does not help, the arity guessing has to be delayed into the runtime.
-
-**Bindings to JS world:**
-
-When we create bindings for high order functions in the JS world, we would like to have native uncurried functions which behave the same as JS world -- no semantics mismatch.
-
-
-## Generalized uncurried calling convention in this release
-
-Before release 7.3, we had introduced uncurried calling convention, however, it has serious limitations -- uncurried functions can not be polymorphic, it does not support labels, the error
-message leaks the underlying encoding -- now all those limitations are gone!
-
-**Previously:**
-
-
-
-
-
-
-
-The error messages above are cryptic and hard to understand. And the limitation of not supporting recursive functions make uncurried support pretty weak.
-
-Now those limitations are all gone, you can have polymorphic uncurried recursive functions and it support labels.
-
-
-
-
-
-The error message is also enhanced significantly
-
-### When the uncurried function is used in curried
-
-```reason
-let add = (. x, y ) => x + y;
-
-let u = add (1, 2)
-```
-
-The old error message:
-
-```
-Error: This expression has type (. int, int) => int
- This is not a function; it cannot be applied.
-```
-
-The new error message
-
-```
-Error: This function has uncurried type, it needs to be applied in ucurried style
-```
-
-### When the curried function is used in the uncurried context
-
-```reason
-let add = ( x, y ) => x + y;
-
-let u = add (.1, 2)
-```
-
-The old error message:
-
-```
-Error: This expression has type (int, int) => int
- but an expression was expected of type (. 'a, 'b) => 'c
-```
-
-The new error message:
-
-```
-Error: This function is a curried function where an uncurried function is expected
-```
-
-### When arity mismatch
-
-```reason
-let add = (. x, y ) => x + y;
-
-let u = add (.1, 2,3)
-```
-
-The old message:
-
-```
-Error: This expression has type (. int, int) => int
- but an expression was expected of type (. 'a, 'b, 'c) => 'd
- These two variant types have no intersection
-```
-
-The new message:
-```
-Error: This function has arity2 but was expected arity3
-```
-
-Note the generalized uncurry support also applies to objects, so that you can use `obj##meth (~label1=a,~label2=b)`.
-
-The only thing where the uncurried call is not supported is optional arguments, if users are mostly targeting JS runtime, we suggest you can try uncurry by default and would like to hear your feedback!
-
-You can already test it today by `npm install bs-platform@7.3.0-dev.1` (Windows support will be coming soon).
diff --git a/_blogposts/archive/2020-04-13-bucklescript-release-7-3.mdx b/_blogposts/archive/2020-04-13-bucklescript-release-7-3.mdx
deleted file mode 100644
index 7be10a2aa..000000000
--- a/_blogposts/archive/2020-04-13-bucklescript-release-7-3.mdx
+++ /dev/null
@@ -1,226 +0,0 @@
----
-author: hongbo
-date: "2020-04-13"
-badge: release
-title: Announcing BuckleScript 7.3
-description: |
- Featuring major improvements like Generalized Uncurry Convention Support and
- unit value to undefined compilation.
----
-
-## Overview
-
-We are happy to announce that `bs-platform@7.3` is available for testing, you
-can try it with `npm install bs-platform@7.3.1`.
-
-For those unfamiliar with bs-platform, it is the platform for compiling
-[ReasonML](https://reasonml.github.io/) and [OCaml](https://ocaml.org/) to fast
-and readable JavaScript.
-
-
-This is a major release with some highlighted features as below:
-
-## Generalized uncurry calling convention support
-
-You can use an uncurried function as conveniently as a curried one now, this is
-an exciting change that we wrote a [separate
-post](https://bucklescript.github.io/blog/2020/03/26/generalize-uncurry) for
-details.
-
-
-For uncurried support, we also fixed a long standing
-[issue](https://github.com/BuckleScript/bucklescript/issues/4274) so that type
-inference follows naturally using the new encoding.
-
-```reason
-bar
- -> Belt.Array.mapU((.b)=>b.foo /*no type annotation needed */)
-```
-
-## The `unit` value now compiles to `undefined`
-
-In ReasonML, when a function does not return any meaningful value, it returns a
-value that is `()` of type `unit`. In native backend, the dummy value `()` is
-compiled into a const zero. We used to inherit this in JS backend as well.
-However, this is a semantics mismatch since in JS, if the function does not
-return anything, it defaults to `undefined`. In this release, we make it more
-consistent with JS: compiling `()` into `undefined`. Since in JS, `return
-undefined` can be ignored in tail position, this leads to some other nice
-enhancement.
-
-
-```reason
-let log = x => Js.log(x)
-```
-
-The generated code used to be
-
-```js
-function log(x){
- console.log(x);
- return /* () */ 0;
-}
-```
-
-It's now
-
-```js
-function log(x){
- console.log(x)
-}
-```
-
-## Various improvements in code generation
-
-We have increased the readability of the generated code in several common
-places, we believe that we reached *an important milestone* that if you write
-code using features that have counterparts in JS, the generated code is
-readable. This is not a small achievement given that quite a lot of the
-compiler code base is shared between native backend and JS backend.
-
-There are some features that are not available in JS, for example, complex
-pattern matches, the readability of those pieces of generated code will
-continue being improved.
-
-Take several enhancement below as examples:
-
-### Meaningful pattern match variable names
-
-```reason
-let popUndefined = s =>
- switch (s.root) {
- | None => Js.undefined
- | Some(x) =>
- s.root = x.tail;
- Js.Undefined.return(x.head);
- };
-```
-
-```diff
-function popUndefined(s) {
-- var match = s.root;
-- if (match !== null) {
-- s.root = match.tail;
-- return match.head;
-+ var x = s.root;
-+ if (x !== undefined) {
-+ s.root = x.tail;
-+ return x.head;
- }
-
- }
-```
-
-When pattern match against a compounded expression, the compiler used to use a
-temporary name `match`, now we employ better heuristics to generate meaningful
-names for such temporary variables.
-
-### Eliminate intermediate variable names when inlining
-
-```diff
- function everyU(arr, b) {
- var len = arr.length;
-- var arr$1 = arr;
- var _i = 0;
-- var b$1 = b;
-- var len$1 = len;
- while(true) {
- var i = _i;
-- if (i === len$1) {
-+ if (i === len) {
- return true;
-- } else if (b$1(arr$1[i])) {
-- _i = i + 1 | 0;
-- continue ;
-- } else {
-+ }
-+ if (!b(arr[i])) {
- return false;
- }
-+ _i = i + 1 | 0;
-+ continue ;
- };
- }
-```
-
-The above diff is the generated code for `Belt.Array.everyU`, the intermediate
-variables were introduced when inlining an auxiliary function, such duplication
-were removed in this release.
-
-### Flatten if/else branch making use of JS's `early return` idiom
-
-Take the same diff from above, you will notice that the second `else` following
-`if(..) continue` is removed.
-
-Below are similar diffs benefiting from such enhancement:
-
-```diff
- function has(h, key) {
-@@ -133,21 +123,18 @@ function has(h, key) {
- var nid = Caml_hash_primitive.caml_hash_final_mix(Caml_hash_primitive.caml_hash_mix_string(0, key)) & (h_buckets.length - 1 | 0);
- var bucket = h_buckets[nid];
- if (bucket !== undefined) {
-- var key$1 = key;
- var _cell = bucket;
- while(true) {
- var cell = _cell;
-- if (cell.key === key$1) {
-+ if (cell.key === key) {
- return true;
-- } else {
-- var match = cell.next;
-- if (match !== undefined) {
-- _cell = match;
-- continue ;
-- } else {
-- return false;
-- }
- }
-+ var nextCell = cell.next;
-+ if (nextCell === undefined) {
-+ return false;
-+ }
-+ _cell = nextCell;
-+ continue ;
- };
- } else {
- return false;
-@@ -155,17 +142,17 @@ function has(h, key) {
- }
-```
-
-```diff
---- a/lib/js/belt_List.js
-+++ b/lib/js/belt_List.js
-@@ -15,9 +15,8 @@ function head(x) {
- function headExn(x) {
- if (x) {
- return x[0];
-- } else {
-- throw new Error("headExn");
- }
-+ throw new Error("headExn");
- }
-```
-
-### For loop minor-enhancement
-
-```diff
- function shuffleInPlace(xs) {
- var len = xs.length;
-- for(var i = 0 ,i_finish = len - 1 | 0; i <= i_finish; ++i){
-+ for(var i = 0; i < len; ++i){
- swapUnsafe(xs, i, Js_math.random_int(i, len));
- }
-- return /* () */0;
-+
- }
-```
-
-Reason's `for .. in` only provide closed interval iterating, so it is quite
-common to write `for (i in 0 to Array.length(x) - 1) { .. }`, we did the
-tweaking above to make the generated code more readable.
-
-A full list of changes is available in our [Changelog
-file](https://github.com/BuckleScript/bucklescript/blob/master/Changes.md#73).
-
diff --git a/_blogposts/archive/2020-05-06-a-story-of-exception-encoding.mdx b/_blogposts/archive/2020-05-06-a-story-of-exception-encoding.mdx
deleted file mode 100644
index 065681d34..000000000
--- a/_blogposts/archive/2020-05-06-a-story-of-exception-encoding.mdx
+++ /dev/null
@@ -1,150 +0,0 @@
----
-author: hongbo
-date: "2020-05-06"
-previewImg:
-title: New Exception Encoding in BuckleScript
-description: |
- Highlights of our newest changes to the internal representation of exceptions
- and how it will provide better stacktraces to our users.
----
-
-## Upcoming Changes
-
-We just recently made some significant improvements with our new exception encoding and we find it so exciting that we want to highlight the changes and explain a little bit how exceptions work when compiling to JS.
-
-The new encoding allows us to provide proper, clear stacktrace information whenever a Reason/OCaml exception is thrown. This is particularly important when you have some code running in production that needs to collect those stacktrace for diagnostics.
-
-What's the difference?
-
-```reason
-exception My_exception { x : int};
-
-let loop = () => {
- for (i in 0 to 100) {
- if (i == 10) {
- raise (My_exception { x : i})
- };
- };
-};
-loop ();
-```
-
-When we compile and run this piece of code with the old exception encoding, this is what we'd get:
-
-```
-exn_demo$node src/exn_demo.bs.js
-
-/Users/hongbozhang/git/exn_demo/src/exn_demo.bs.js:11
- throw [
- ^
-[ [ 'Exn_demo.My_exception', 1, tag: 248 ], 10 ]
-```
-
-With our new improvements, we now get way better results:
-
-```
-bucklescript$node jscomp/test/exn_demo.js
-
-/Users/hongbozhang/git/bucklescript/jscomp/test/exn_demo.js:10
- throw {
- ^
-{
- RE_EXN_ID: 'Exn_demo.My_exception/1',
- x: 10,
- Error: Error
- at loop (/Users/hongbozhang/git/bucklescript/jscomp/test/exn_demo.js:13:20)
- at Object.| JavaScript | -ReScript | -
|---|---|
| - ``` - const myFun = (x, y) => { - const doubleX = x + x; - const doubleY = y + y; - return doubleX + doubleY; - }; - ``` - | -- ``` - let myFun = (x, y) => { - let doubleX = x + x - let doubleY = y + y - doubleX + doubleY - } - ``` - | -
| JavaScript | -ReScript | -
|---|---|
| - ``` - let result = (function() { - const x = 23; - const y = 34; - return x + y; - })(); - ``` - | -- ``` - let result = { - let x = 23 - let y = 34 - x + y - } - ``` - | -
children- } - type prefix = [#W | #E] - let compactErrorLine = (~highlight=false, ~prefix: prefix, locMsg: Api.LocMsg.t) => { - let {Api.LocMsg.row: row, column, shortMsg} = locMsg - let prefixColor = switch prefix { - | #W => "text-orange" - | #E => "text-fire" - } - - let prefixText = switch prefix { - | #W => "[W]" - | #E => "[E]" - } - - let highlightClass = switch (highlight, prefix) { - | (false, _) => "" - | (true, #W) => "bg-orange-15" - | (true, #E) => "bg-fire-90 rounded" - } - -
- {React.string("Type + / - followed by a number or letter (e.g. +a+1)")} -
-
- {HighlightJs.renderHLJS(~code=jsCode, ~darkmode=true, ~lang="js", ())}
-
- | Ready({result: Conv(Success(_))}) => React.null
- | Ready({result, targetLang, selected}) =>
- - {React.string( - "You are currently looking at the v12 docs, which are still a work in progress. If you miss anything, you may find it in the older v11 docs ", - )} - {React.string("here")} - {React.string(".")} -
-