A short history of ReScript (BuckleScript)

Given that there seems to be some confusion, I’ve written up a small post about it, which may be helpful: How does ReScript affect me? - DEV Community

5 Likes

Thank you @yawaramin for that blog post. Very nice, clear summary.

This does not affect me at all, but to clarify what sort of thing can be confusing to an outsider:

I am a BuckleScript user with OCaml syntax
In this case you don’t actually need to do anything; OCaml syntax is not going away.

Here the link is to a post from August “A Note on BuckleScript’s New Syntax and Its Future Support Commitments”, which is preceded by a note, “Important: This is an archived blog post, kept for historic reasons. Please note that this information might be terribly outdated.”

Maybe the archived/outdated flag was added automatically by software, but if I was someone who had been using OCaml syntax with BuckleScript, and that post was all that I could find about that use, I would not trust that support for OCaml syntax would continue.

(The fact that there was no current statement about this was also one of the things that at one time contributed to my feeling that it was not time for someone like me to explore or talk to those unfamiliar with OCaml about Reason or ReScript or Bucklescript. I still think it’s not the time for me, but that’s not really important. I’ve appreciated some of the things mentioned here, including your blog post, @yawaramin. It’s nice to get a clearer understanding of what’s going on with ReScript and Reason, even though it doesn’t affect me currently. I’m looking forward to future developments with ReScript and Reason/OCaml.)

1 Like

Just unlurking to say this: I’m looking for an alternative to Elm (which is great but has some problematic downsides) and after considering the Haskell based solutions, I had decided Ocaml was the way to go (if only because the language is liberal enough for my taste and the prospect of a dual server/client language is appealing, not to mention owl).

Months ago I discovered BuckleScript and JSOO.
JSOO (and its surrounding elements) looks great – barring the notion of running atop a compiled version of the ocaml bytecode interpreter, which worried me a bit (on the potential performance aspect).

Given this when I discovered the BuckleScript → Rescript change I was a bit disappointed, like if a viable option had just disappeared. Now if you say it was never really that viable I take your word. This was a prospective and of course no damage has been done !

But indeed I was confused :slight_smile:

Just fyi, one of the default templates that BuckleScript (now ReScript) ships with is GitHub - OvermindDL1/bucklescript-tea: TEA for Bucklescript , an Elm architecture clone ported over to OCaml/BuckleScript.

At the very least there is one production user of bucklescript-tea: Darklang.

2 Likes

@bobzhang Thank you for the summary. Your work is great!

On the question of whether existing code will keep working, I think the answer is a definitive yes. However, many people seem to think that answer might be no and that’s causing some stress. I’m not on any of the relevant teams, but I’d like to offer the following clarifications which I hope will help:

  • If your code is in ReasonML syntax and you were compiling with BuckleScript, then the recommendation is to convert your code to the new ReScript syntax. However, the ReasonML syntax will continue to be supported for a long time at the current version of that syntax. Newer versions of ReasonML syntax will not be supported.
  • If your code is in ReasonML syntax and you compiled with OCaml, then everything will keep working as it did before, but this entire toolchain is no longer part of what is now called ReScript.
  • If your code is in OCaml syntax and you compiled it with both OCaml and Bucklescript, then everything will keep working. The recommendation is that this kind of code be relatively simple in the sense that you’re not using bleeding edge features of the OCaml language. There might also be some issues with ppx’s (which I don’t completely understand).

Can anyone provide an example of code that has or might suddenly stop working. I’m interested to know what kind of code this is and what change makes it stop working.

2 Likes

One example is usage of the @@deriving attribute. ReScript now specifically interprets that internally, so PPXs which rely on it won’t work.

Not anymore, apparently they left for F#:

@yawaramin I read your blog only after posting my message. I see I mostly duplicated what you had written. However, I don’t entirely agree with your recommendation not to compile the same code with both OCaml and ReScript. This can avoid a lot of code duplication. Why shouldn’t we do that? Is it only because the tooling for that workflow isn’t well defined. Personally, we don’t find it so hard, though yes definitely there are a bunch of hacks in our build system that I wish we didn’t need.

The alternative is to compile that code with jsoo. That might be a good solution, but I’m curious why that is better. One downside is that if you are using ReScript on the frontend, then you now have OCaml code that compiles to JS, which you then need to write a ReScript binding for. This seems circular since the ReScript is identical to your original OCaml code (modulo concrete syntax).

That’s the backend. They use BuckleScript on the frontend.

1 Like

@c-cube I might be missing it, but I don’t see any mention in that post about any code that stopped working due to the new ReScript.

Ah, I have no idea. I thought they abandoned OCaml entirely, but I stand corrected.

I don’t think anyone’s concerns have been around immediate breakage. To @perry’s point earlier, grousing and doubt exist because some nontrivial number of capable people have found the projects’ intentions/objectives to be unclear, and so previously-held expectations (insert standard disclaimer re: expectations and open source projects) appear to be unsatisfied vis a vis future directions.

1 Like

My recommendation is to use JSOO, or ReScript–not both in the same project. That sounds a bit too over the top :slight_smile:

The reason why I suggested not to use OCaml (native toolchain) in the same codebase with ReScript toolchain is–IMHO it’s not worth the effort for most people. For you, maybe it is–despite all the hacks. But there shouldn’t need to be so many hacks in a maintainable codebase. At a certain point you’re just better off using Spring Boot or whatever.

1 Like

I’m really pleased to see ReasonML finally crediting OCaml in at least some way on its front page. I would prefer it to say “ReasonML is an alternative concrete syntax for the OCaml programming language”, but that’s still better than before. I still think its website is completely confusing for newcomers who aren’t already familiar with OCaml though.

As of ReScript, I’m also happy to see it openly become a standalone language. BuckleScript essentially always was a standalone toolchain nearly impossible to integrate into an OCaml workflow, so there’s going to be a lot less confusion now, I hope. I wish the authors best of luck.

Not to distract from the rest of the thread, but jsoo doesn’t run “atop a compiled version of the ocaml bytecode interpreter”. It compiles the bytecode to javascript. There is no interpreter involved (except the browser), and the perf is usually comparable to hand-written code.

2 Likes

Running JSOO emitted javascript on v8 and mozjs can be amazingly fast in some cases. Some time ago I did a little test program solving prime numbers, using a very simple algorithm (dividing by ascending odd numbers up to the root of the tested number) and it could solve the 100,000th prime under JSOO running in the browser faster (0.29 secs for v8, 0.26 secs for mozjs) than the equivalent code running in native ocaml (0.52 secs). I guess the test case happened to hit a sweet spot for v8’s and mozjs’s JITing of the loops into optimized CPU instructions. Normally JSOO is somewhat slower than native code. (For anyone interested in the comparison, it is here: http://www.cvine.plus.com/primes.tar.xz )

4 Likes

Interesting. I ported the benchmark with some slight modifications to ReScript (OCaml syntax) and get 0.117s with Firefox and 0.094s with Chromium. I haven’t run the JSOO version for comparison, so take this with a grain of salt of course.

Here’s the repo in case you’re interested: GitHub - yawaramin/primes-rescript (requires Node.js to work). I’ve also included the output JS file for easy comparison: primes-rescript/primes.js at main · yawaramin/primes-rescript · GitHub

I believe the only significant difference is that my port isn’t using the onload event; instead, I just placed the <script> tag at the end of the <body>, which guarantees the same effect.

EDIT: sorry, one more fairly significant difference: I’m using ReScript’s built-in lightweight string interpolation, {j|Elapsed time: $time..., instead of Printf.sprintf. But I think it’s a fair showcase of ReScript’s specific advantages.

5 Likes

You have a nice fast machine. By way of comparison, how long does the native ocamlopt code take to solve the prime?

Weirdly, if I put the script tag in the body and omit the Lwt onload event, the JSOO code runs slightly slower for me. Loading it in the head seems to improve the chance of the JITer getting on the fast path, particularly if reloading the page.

Edit By the way, I don’t have rescript installed but if I tweak your rescript-generated primes.js file by omitting the imports of curry.js and caml_int32.js and substituting standard javascript, the rescript version runs slightly faster than the JSOO version in chrome and slightly slower in firefox. So it seems pretty much-of-a-muchness.

To clarify, Dark’s frontend is 50kLOC of Rescript (OCaml syntax) and will continue to be for the foreseeable future. The backend (20kLOC) is being rewritten from OCaml (native+jsoo) into F#. I’m about two months into it and approaching being finished.

Thanks for writing this! I was also extremely confused about what was happening. I had thought there was a still a reasonml project that targeted JS.

I’ll note that it feels like the OCaml syntax for rescript is a second-class-citizen, as lots of things seem to only work with the PPXes that only work on rescript.

1 Like