Introduction to the why
At uSwitch we constantly strive to deliver better value for our customers faster. Ocassionally that means evaluating new tools and technologies. One technology that recently caught our attention is ReasonML. It promises a good, but not overly complex statically types language combined with very solid
Roberto is a recent Set the task mission.
Why use static typing?
Explain the conclusions / facts. that is the purpouse of the article.
ReasonML is an alternate syntax for OCaml that uses Bucklescript compiler backend to output JS. It comes with a set of tools focused on great Developer Experience to write type safe, functional-style programs. The resulting code achieves pretty fast performance and small bundle sizes.
At uSwitch broadband team we have been evaluating ReasonML as a candidate to get static typing on the frontend. The main questions we wanted to answer were:
- What are the features that this new language / platform will provide us?
- How difficult is to integrate in our workflow?
- What does the ecosystem look like?
You can expect most of OCaml features when writing a ReasonML program: Concise syntax, type inference and functional goodies like currying and pattern matching. On top of that any ReasonML module gets exported as CommonJS, so you can use your usual bundler, and publish or consume code from npm in the way you are used to.
ReasonML's type system is sound, meaning that the type system provides semantics to ensure that our code is not going to run into an error at runtime. This is a more powerful type system than Typescript, as a comparison, but it is still pragmatic enough to keep it simple and help you get things done.
ReasonML compiler will output any .re file under the source folder that we specify to the same path under a lib/js/src directory, we can either require those files directly as any other CommonJS module or bundle them together with webpack or any other similar tool.
ReasonML compiling to CommonJS modules means that we can replace our codebase on a module by module basis and migrate in batches. Calling ReasonML functions from the outside world is just requiring the module and calling the function from JS.
Using JS functions (or any runtime value from the environment) from ReasonML requires a bit more of work. Bucklescript provides an external declaration mechanism to do exactly that. We found it to be fairly simple to use; you can reference globals, methods and even interpolate raw output so the compiler knows what to do when translating an specific token to JS. The recommended approach in the official docs is surprisingly pragmatic: when translating your JS codebase start with getting the syntax right, then add the minimum amount of bindings to get it to compile and finally get the types right.
In general we found the community has a very pragmatic approach to solving problems which feels very refreshing. They are not discussing type theory and purity in their ivory tower but trying to get the language to be used in real world scenarios.
Investigating the ecosystem will also give us an idea on how healthy the community is, how fast the project advances and the current lifecycle the platform is in.
| Area | Status |
|---|---|
| Libraries | Complete OCaml standard library, few ports in alpha/beta stage from other libraries |
| Build System | Bucklescript build tools, webpack bs-loader |
| Package Management | npm |
| Stack Overflow | 9 questions |
| Error messages | Elm style, very friendly |
| Editor Support | Atom, VIM, Emacs, VSCode |
| Support Channels | Discord ReasonML |
Ports from JS libraries seem a bit lacking at the moment, prepare yourself to write quite a few bindings to interact with your current code base. On the other hand, the build system, error messages and package management are superb.
Editor support is good, making use of OCaml-merlin, you can expect to have nice overlay type hints, code completion, exhaustive pattern matching and many more things right in your editor.
Stack Overflow is just empty, but the discord community is quite active and friendly.
ReasonML documentation does a good job explaining the syntax and the basic features, but it is lacking an overview on how the platform works as a whole. For anything beyond the simple examples you'll end up searching in google or asking in Discord.
We found the sources of information to be fragmented. To solve most of our problems we had to use a combination of different documents: the official ReasonML docs for syntax and tooling, the Bucklescript manual for JS interops (externals, default modules and some syntax not covered by ReasonML docs) and the OCaml Manual for anything not covered by the previous two sources.
This is not obvious when reading the ReasonML docs for the first time and can be a bit frustrating to realise. This is eased by great tools like ReasonML Tools and Reasonably Typed that help us to move from OCaml syntax to ReasonML and back, and to convert Flow type declarations to ReasonML.
Expect to use those tools heavily in combination with OCaml tutorials when creating your first programs.
After understanding the pros and cons of the platform, we created a minimal build configuration to be able to get a faster development cycle. Failing fast is important when learning a new language and we don't want to be spending more time compiling than coding.
The project we created consists of a small enviroment to play with the language, you can find it here:
https://github.com/rlucha/reasonml-minimal-config
You'll need to install the ReasonML platform before the tool, just follow the step from the official Docs.
https://facebook.github.io/reason/jsWorkflow.html
This is what you can expect to find:
- Small static http server using Browsersync
- Bundling with webpack, including stats.json to check with any bundle analyzer
- Source code files watching and reloading of both the bundle and the http server.
- Production ready minified file with dead code elimination
In a reasonable amount of time we got a fair amount of features working, we think it will be easy enough for us to incrementally adopt the technology and get something into production, so for now we'll be using it in a pet project to gain more knowledge and we hope to get it into our main codebase eventually.
It has been one of the most pleasurable experiences we have had with languages that transpile to JS so far, and the ReasonML team has done a great job at making it approachable.
Hello, nice article. A few notes:
bytecode, native code, or JavaScript. BuckleScript is an OCaml-to-
JavaScript compiler. ReasonML and BuckleScript work really well
together; in fact the BuckleScript npm module
bs-platformcomes withReasonML support built-in.
etc. module types. You have the flexibility to choose.
just say 'ReasonML/OCaml is pragmatic' and leave it at that.
or Rollup or Browserify etc.
which has a dedicated BuckleScript channel.
you will see 'syntax error' and a line and column number which may be
pretty far from the actual error. It takes some getting used to.
Cheng Lou's 'Better Errors' tool is in development to help fix that.