Since dune got the integration with Melange (and Ahrefs migrated to Melange Ahrefs is now built with Melange) I wanted to write about the benefits of using it.
I wrote a blog post comparing Melange with the previous compiler (BuckleScript/ReScript) and what’s possible. I tried to be objetive and focus only on the technical parts of it.
Hi! Thanks for the write and for sharing I posted a question a few days back that seems on topic, but which, afaict, is not answered in your post (which, iiuc, is target at reason/rescript users more than OCaml users):
As a Jsoo user, my naive assumption was that anything that didn’t involve system interactions would compile, but this seems to be the case. I couldn’t find any readily available documentation explaining these limitations tho, nor what is required to make dependencies available for code that comiles via melange. Any pointers here would be helpful and gratefully received
We should make it probably clearer on the documentation, I will open an issue. For now let me try to draft some requisites from the top of my head.
Making a library “melange ready” there are the following rules:
To have all dependencies modes melange
To have dune 3.1 and OCaml 5.0/5.1 (depending on Melange’s version)
Don’t rely on system dependencies (similar on jsoo)
Having all dependencies modes melange is the biggest difference from jsoo, where you can add modes js in your “entry” and all subsequent libraries will be compiled to js (ofc unless some system dependency is used and no shim is available).
Having recently moved a code base from rescript to melange: I think it’s just great!
(the server/back end code is in OCaml)
*I tried JSOO and didn’t find sufficient documentation to get started with a typical web FE application, like using it with a bundler, CSS modules, translations etc.
*JS as JavaScript not JaneStreet
Some of the tradeoffs with rescript, that you mentioned
Variants representation as strings : I really miss this, it makes interop with css, DOM, JS libraries much simpler
uncurry by default : I like uncurry by default (in JS land), the generated code is much more idiomatic and I wish there was a middle ground that both allows interop with OCaml, and doesn’t generate JS with ugly curry calls.
but I would trade all of these to be able to share code between the BE and FE.
Thanks for sharing the lessons learnt for having a bigger code base in Rescript and the limitations that come with that. I’m not a company, so when making choices about technologies to use for personal projects I find such reads very reassuring - I don’t want to be the first person to encounter every typical workflow problem.
(a general issue I find with OCaml is there’s not enough noise from companies using it - is it used successfully for web applications, am I going to be the first person to need to solve translations etc.)
I found that the web is very extensive, heavily dependent on specific use cases, and uniquely different from one another.
There’s definitively not a bunch of companies sharing their solutions to the world when they work with ReScript/Melange, and I only can talk about mine.
Recently, I was discussing the state of functional programming for Browser, and my colleague was kind of disappointed the state of client-side programming in F#+Fable. He rants that although that React library is somehow usable, other popular libraries like Redux and not really supported on F# side.
Is situation better with Melange? Is it reasonable to desire Redux on OCaml side, or not?
While I understand a lot of React apps built before 2020 use Redux heavily, I find that today it’s fine to just use React’s built-in useReducer and useContext if you want some typed state machine code for your global states.
Is writing the melange bindings for redux the pain point?
Thanks for writing up this blog post. It’s great to have more talk about using OCaml for the web.
Curious that you mentioned a few times that multicore is not supported, could you say a bit more about why? I would naively think that effects could be used to implement async/await functionality from JavaScript to get concurrency even if there is only a single domain.
Currently multicore isn’t a feature supported by Melange since it can’t benefit extensively, due to the nature of JavaScript being single threaded.
I have found the need of using a store (globally or per domain/page) when working on a SPA, I have used GitHub - rickyvetter/reductive: Redux in Reason in the past or implement a store by hand to manage it.