JavaScript is not just the browser language, it’s also the only existing cross platform language. It is truly everywhere: users don’t need to install binaries or use package managers to access software, just a link will work.
Another important factor is that the JavaScript VM is quite fast and keeps getting faster. The JavaScript platform is therefore increasingly capable of supporting large applications.
BuckleScript is mainly designed to solve the problems of large scale JavaScript programming:
- Type-safety
-
OCaml offers an industrial-strength state-of-the-art type system and provides very strong type inference (i.e. No verbose type annotation required compared with TypeScript), which proves invaluable in managing large projects. OCaml’s type system is not just for tooling, it is a sound type system which means it is guaranteed that there will be no runtime type errors after type checking.
- High quality dead code elimination
-
A large amount of web-development relies on inclusion of code dependencies by copying or referencing CDNs (the very thing that makes JavaScript highly accessible), but this also introduces a lot of dead code. This impacts performance adversely when the JavaScript VM has to interpret code that will never be invoked. BuckleScript provides powerful dead-code elimination at all levels:
-
Function and module level elimination is facilitated by the sophistication of the type-system of OCaml and purity analysis.
-
At the global level BuckleScript generates code ready for dead-code elimination done by bundling tools such as the {closure}[Google closure-compiler].
-
- Offline optimizations
-
JavaScript is a dynamic language, it takes a performance-hit for the VM to optimize code at runtime. While some JS engines circumvent the problem to some extent by caching, this is not available to all environments, and lack of a strong type system also limits the level of optimizations possible. Again, BuckleScript, using features of the OCaml type-system and compiler implementation is able to provide many optimizations during offline compilation, allowing the runtime code to be extremely fast.
- JS platform and Native platform
-
Run your programs on all platforms, but run your system faster under specific platforms. JavaScript is everywhere but it does not mean we have to run all apps in JS, under several platforms, for example, server side or iOS/Android native apps, when programs are written in OCaml, it can also be compiled to native code for better and reliable performance.
While a strong type-system helps in countering these problems, at the same time we hope to avoid some of the problems faced in using other offline {transpile-list}[transpilation systems]:
- Slow compilation
-
OCaml byte-code compilation is known to be fast (one or two orders of magnitude faster than other similar languages: Scala or Haskell), BuckleScript shares the same property and compiles even faster since it saves the link time. See the speeds at work in the {BuckleScript-playground}[playground], the native backend is one order faster than the JS backend.
- Un-readable JS Code and hard to integrate with existing JS libraries
-
When compiling to JavaScript, many systems generate code, that while syntactically and semantically correct is not human-readable and very difficult to debug and profile. Our BuckleScript implementation and the multi-pass compilation strategy of OCaml, allows us to avoid {name-mangling}[name-mangling], and produce JavaScript code that is human-readable and easier to debug and maintain. More importantly, this makes integration with existing JS libraries much easier.
- Large JS output even for a simple program
-
In BuckleScript, a
Hello world
program generates 20 bytes JS code instead of 50K bytes. This is due to BuckleScript having an excellent integration with JS libs in that unlike most JS compilers, all BuckleScript’s runtime is written in OCaml itself so that these runtime libraries are only needed when user actually calls it. - Loss of code-structure
-
Many systems generate JavaScript code that is essentially a big ball of mud. We try to keep the original structure of the code by mapping one OCaml module to one JS module.