ReScript a awsome Option dismissed!



Before I will tell you the WHY

I should list the reasons I was looking into ReScript:

  • functional programming
  • support for strict types
  • pattern matching

This is basic stuff, but as a programming language is used in a production setup there are some more requirements:

  • Code Editor language support
  • test driven development
  • access to many libraries solving common problem or providing access to APIs
  • embedding or providing libraries
  • Visual Debugging
  • Source level Error and Exception logging
  • Big Community to support and drive the development of new features
  • Build pipeline which can handle all assets
  • deployment pipeline to support continues integration and deployment
  • error, exception and performance monitoring in production (e.g. NewRelic, Sentry,...)
  • can be used fullstack (e.g., browser, native desktop apps, native mobile apps, backend, scripting) and allows isomorphic code parts
  • can be uses as a cloud function (e.g. AWS Lambda)

I have been using and trying many languages (TurboProlog, Oberon, Prograph) in the last 35 years and mostly failed to productively use a programming language or a framework based on one or more of the following facts:

  • Community to small to have enough experience with all possible problems
  • only payed support
  • insufficient documentation
  • no visual step debugging in the original

I created the following rules for me which also work for frameworks:

  • How big and active is the Community, specifically are there enough contributors or is it used by an enterprise in production
  • Does the Ecosystem cover all my required use cases
  • Is there tooling and language support by the major code editors
  • Can I step through the code an inspect / modify variables and the stack at any time

Let´s get back to ReScript and evaluate what exists and what does not exist. All this is based a first interaction with ReScript and there might be wrong assumptions based on the information I was able to find on the website and the forums.

Development setup

ReScript provides a git template for project setup with all the required additional configuration files.

git clone https://github.com/rescript-lang/rescript-project-template

Opening the folder in VS Code shows the following file structure:

1> lib/bs
2> node_modules
3> src
4 Demo.bs.js
5 Demo.res
6 .gitignore
7 .merlin
8 bsconfig.json
9 packages.json
10 README.md

Next step is to install the rescript-vscode plugin which adds language support to VS Code.

show ReScript language support in editor
[show ReScript language support in editor]

The package.json provides 3 scripts:

  • build - compile the application to JavaScript
  • clean - ??
  • start - watch src directory and compile on change

The file bsconfig.json contains the compiler configuration with the default output module format CommonJS (can be changed to "es6" for the new ES Module format)


Debugging

Is always my second step when testing a new programming language or framework. Sometimes a language does provide debugging but the framework breaks the easy way by using child processes which make it many times harder to connect to the process which needs to be debugged.

This is what I was able to find:

  • Logging with JS.log or other logging libraries
  • adding a debugger statement which will invoke the debugger of JavaScript at runtime
  • using tests

Debugging the output of the compiler with the typical Visual Debuggers Tools available for JavaScript is possible but this will not always help as there are some optimisations going on in the compiler and all the type structures are missing in JavaScript.

The problem is not new and was solved for all compiling languages a long time ago. In the JavaScript Ecosystem the solution is called sourcemaps and are supported by most of the other languages which use the JavaScript core to to run applications.

A sourcemap is as the name suggest a file which links the position of code in the compiled output back to the original source code. A sourcemap can be embedded or referenced.

So what is the status of sourcemap support with ReScript:

  • it is under the most upvoted issues of all time on the rescript-compiler repository

  • the issue was closed on 24th April 2020 by chenglou a core developer with:

    Source maps are designed to be best effort. Not to mention a pain to properly implement and maintain over years even under the best-effort design. There are emphasis and de-emphasis in a toolchain. Unfortunately, in this case, our decision is to de-emphasize this particular feature. Particularly when our desire is for the toolchain to be robust and simple (well ok, several parts definitely aren’t so right now...)

  • there is some discussion in the ReScript forum

  • not mentioned on the road map

There is currently nothing which shows any plans to fix this problem which is also very crucial for making the language suitable for beginners.

Production

About 2010 I learned about NewRelic which was a free offer of my cloud provider at that time. NewRelic is a tool which is installed on your production system and continuously monitors your application stack for exceptions, performance and application errors.

Where it differs from logging and any other application which aggregates, and analyses logs from the whole stack (e.g., React Frontend, Node Backend, MySQL Server) is that in case of an error it will include the context of the whole stack and dependent of the integration with your framework this will include application specific data as user id and a breadcrumb of activities which happened before the incident.

A breadcrumb is more than a stack trace as it contains application context which helps later to simulate the problem in a local development environment.

Currently I use Sentry.io which is a similar tool with a wide range of supported programming languages and frameworks. Whenever Sentry detects an exception on production, it will not only provide you with the context, but it will also show you the context of the exception in the original source code which makes it much faster to decide on the fastest way to fix the problem.

Not providing sourcemap breaks my workflow on 2 places which makes ReScript not usable for professional work.

4) What about my other requirements?

Community

You cannot compare it with JavaScript or even Typescript but it has grown over the last couple of years and has its own conferences. Many questions can be solved by adapting solutions from the JavaScript Ecosystem.

Documentation

The website provides a good start for the language features but there is still need for a more use case oriented approach which show on examples on how to implement frontends, backend including external libraries from the JavaScript ecosystem.

The success of JavaScript comes partly from a Hugh community with a vastly amount of tutorial covering all aspects of problems. In case of ReScript partly targeting people with a JavaScript background it would help to create a section with recipies for maping typical scenarios to ReScript. Destructing Arrays does not support ...tail and the only clue I found in the documentation was to use pattern matching as a better solution. I think the right way would be to convert Arrays to Lists.

Libraries

Theoretical you can use any JavaScript library from NPM but you need to create a binding which is not a process a beginner is able to handle and currently there are only a couple of bindings for some of the more well-known libaries - e.g:

  • GraphQL
  • React JS
  • React Native (iOS, Android)
  • Jest
  • Snowpack
  • ...

The binding for the Node JS standard library to access streams, files is not finished.

Language

I was looking into ReScript as a functional language. There is the included standard library called Belt which provides a basic set of features: Options, Results (Either) but uses a data first approach which is supported by a specific pipe operator. The alternative is a library called relude which offers the full set of typical

The big benefit compared to Typescript is the much easier Type handling which allows to use less type annotations without losing type safety.

ReScript does not support all JavaScript features which is a good thing when the feature is only a variant as async / await for promises which can be much better mapped by Monads (here is a proposal for a solution).

But Generators (function* / yield) are critical when you deal with infinity streams of data which should not be buffered in memory. Except for a library which provides a binding to the JavaScript generators, the documentation has no information on this topic but there was an issue on github. The library warns to use itself for anything except communication with external JavaScript libraries.

Conclusion

ReScript resonated in many aspects with me and my requirements but I have learned in the past that I should not compromise on a proper debugging and production error handling.

I still hope for sourcemaps and have set a google alert to inform me about all changes in this area.

Write a response on Medium