
Reason ML toolchain - thangngoc89
https://khoanguyen.me/reasonml-toolchain/
======
m0meni
I've been following ReasonML pretty closely because, to me, it looks like the
most promising compile-to-js language (functional, static types, but
practical), and moreover, it can really bring a whole new set of people to the
OCaml ecosystem, improving the tooling there. Idealistically, Reason is the
language that lets you target any platform by either compiling to JS or native
code.

That said, I recently tried rewriting some code, specifically a canvas-based
game, in Reason, and while the language itself was amazing, the interop with
the mutable JS canvas API was really annoying. To be honest though, not sure
if games is what Reason is meant for so it's not a big deal. It's a great fit
for React, which really leans heavily on the functional paradigms that Reason
promotes.

Also given that FB has rewritten 50% of messenger in Reason, I don't see it
dying any time soon. So here's hoping that it keeps growing and the tooling
improves. I'd definitely like to see it become more beginner friendly, and
additionally, I'd like to better understand how to interop with existing OCaml
libraries and target the native platforms.

~~~
k__
I found the interopt a bit cumbersome too, but I guess this is what you have
to pay for a 100% typed codebase :/

I saw some people wrote games with Reprocessing, maybe this helps.

[https://github.com/Schmavery/reprocessing](https://github.com/Schmavery/reprocessing)

~~~
thangngoc89
Hey author here,

Here is a successful story [1] of using reprocessing for making cross platform
game (Android, iOS, macOS and Web) from Jared Forsyth

    
    
      [1] https://jaredforsyth.com/posts/making-a-cross-platform-mobile-game-in-reason-ocaml/

------
osteele
If you're interested in ReasonML, you may also be interested in Elm
[http://elm-lang.org/](http://elm-lang.org/).

Coming from JavaScript / React / Redux / Flow, ReasonML initially looked more
familiar, but I still found Elm easier to pick up. Elm has a more unified
feel. ReasonML read to me as an assemblage of components — each of them high
quality, and expertly integrated, but it still felt like more different pieces
all to learn at once. YMMV.

OTOH, you can't (currently) use Elm to write a native mobile app.

~~~
sridca
And if you are interested in Elm, but felt limited by the language, you may
also be interested in PureScript or Haskell.

[http://purescript-pux.org/](http://purescript-pux.org/)

[https://haskell-miso.org/](https://haskell-miso.org/)

[http://docs.reflex-frp.org/en/latest/](http://docs.reflex-frp.org/en/latest/)

~~~
splintercell
I have the same concern, what is the performance of these frameworks in
comparison to Elm? Elm is super fast compared to React and Angular [1], but
what about these frameworks?

1\. [https://www.codementor.io/rudolfolah/elm-vs-react-
developmen...](https://www.codementor.io/rudolfolah/elm-vs-react-development-
performance-compare-603dyh83m)

~~~
hazza1
Framework performance should rarely be an issue in normal use, by super fast
you're talking about milliseconds of difference to toggle hundreds of todo
item.

~~~
aaron-lebo
It's worth being aware that the Haskell approach (and quite a few of these
functional langs) add a lot of size to your bundle.

Hello world in that Haskell library was 1 MB last time it was posted.

------
kbenson
I was looking into ReasonML a few weeks back because the promise of whatr it
offered was so great. Write in one language, and run on the server and on the
client, but allow the server to be compiled natively for speed. This really
appealed to me, especially because there are some times that I really wish I
had some utilities I had written on the back-end available on the front end.

Unfortunately, what you appear to have currently is that a lot of the tools
and utilities you would want to use in ReasonML are written in either JS of
Ocaml, and reply on the interop when you target that platform. Want an ORM?
There's a couple, but they are all targeted at Ocaml, so you either compile to
native and link or try to port the Ocaml source of it to ReasonML (maybe
automatically?) and maintain it. Want a web router/framework? There's a lot
written in JS, but you'll be configuring and writing some JS most likely to
get it to work, and no compiling that natively. This is a recurring theme.
Most robust larger packages are in one language or another, which causes
problems for anyone wanting to leverage the inherent advantages of both target
formats.

What it seems to come down to is that Reason needs a whole lot more software
written in Reason so it's more flexible. Being able to use Ocaml and JS
packages is a feature and liberating, nut _having_ to use Ocaml or JS packages
ends up putting constraints on your project. ReasonML has a lot of promise,
but at least for what I was excited about, it can't deliver. _Yet_.

~~~
nv-vn
Any Reason code can be linked to OCaml code, because OCaml = Reason. In fact,
they are only syntactically different. That is, Reason is an alternate syntax
for OCaml. BuckleScript/js_of_ocaml can be used in either language, which is
to say that any OCaml code can be compiled to JS libraries assuming there are
no dependencies that will fail on JS (no need to convert to Reason code or
anything).

> Being able to use Ocaml [...] packages is a feature

It's not, it's a necessity. OCaml and Reason are the same language; it's not
like Erlang vs. Elixir which both run on BEAM.

~~~
kbenson
Are you saying pure Reason,possibly with some JS interop isn't possible?
Because that sounds like not using an Ocaml packages to me, which means they
aren't a necessity.

~~~
nv-vn
Pure Reason exists, but you can just use `refmt` to convert any OCaml code to
Reason (which isn't even necessary, since they both get compiled to the same
thing and are stored in the same syntax tree).

~~~
kbenson
What I was commenting on was the statement that being able to use Ocaml
packages is a _necessity_ , and specifically as a rebuttal to my saying being
able to use them is a feature.

The implication I get from that is that pure ReasonML to JS without Ocaml
packages is not possible, which is why I asked.

There of course may be some difference on what people consider an Ocaml
package, but I would consider anything ReasonML comes with as available in the
core as not an Ocaml package, even if that's what provides the support
underneath it all, as it's now part of the ReasonML spec (and if the Ocaml
package was deprecated, they would find some other way to provide the same
underlying functionality so the API did not change).

In any case, that statement about it being a necessity confused me.

~~~
nv-vn
Sorry, to clarify I mean that by design OCaml = Reason. The only way it would
not be possible to link the two would be with artificial restrictions. Though
they are very different looking, they share the exact same semantics, type
system, module system, compiler pipeline, etc. Past parsing, the two languages
become the same. I used necessity to mean that for ReasonML to exist, it must
be possible (rather than that all Reason programs must necessarily import
native OCaml code).

------
_delirium
Thanks, this was helpful as someone who's interested in this set of tools but
hasn't been following closely enough to understand how they all fit together
(e.g. why there's both js_of_ocaml and Bucklescript, and how ReasonML fits
into this).

For my own needs, it still seems unclear which way I should go though. The
attractive thing about the tools to me is that you can write code that
compiles to native and web, in a more or less MLish way (which I like). But it
seems like either route works for that. I could just write OCaml, using the
regular native toolchain for native compilation, and either Bucklescript or
js_of_ocaml to compile to web. Or, I could use the ReasonML toolchain instead.
If I'm not primarily a JS dev, is there a reason to pick one or the other? The
syntax differences so far don't jump out at me as exciting enough to be
decisive. I guess I could try a small side project in each and see how it
goes.

~~~
m0meni
I think why you'd pick Reason over OCaml boils down to whether you prefer the
Reason syntax more, and perhaps that it'll have more mindshare than OCaml in
the future. I think the question is similar to why you'd pick Elixir over
Erlang.

------
weberc2
Last time I tried Reason, it seemed like the OCaml toolchain was all but
neglected. For whatever reason (no pun intended), it seems like it's assumed
that Reason only targets JS in practice. It seems like the best way to target
the server or desktop is by way of Node. :(

~~~
nv-vn
Reason targets JS programmers. OCaml's toolchain is great honestly, it just
seems like ~85% of Reason users are more focused on the JS parts of the
language, so what happens is the new users from Reason don't really do much to
contribute to the native toolchain (though any libraries they write can mostly
be used with the native toolchain, which is really nice!). The other thing is,
most of the compiler programmers came to OCaml because it was an ML, and I
think for the most part this group will continue to use the ML syntax and
self-selects for the group that prefers it. So in reality, it's a little bit
crazy to expect the Reason users to be the ones rapidly changing the
toolchain. That said, this will continue to bring more attention to OCaml and
hopefully more funding that can help solidify things like multicore, modular
implicits, and everything else making its way through the compiler development
pipeline at 2mph.

~~~
weberc2
> So in reality, it's a little bit crazy to expect the Reason users to be the
> ones rapidly changing the toolchain.

That's too bad, because all of the marketing (at least around the time I
initially looked into it) was something like "OCaml for humans". The JS bit
was mentioned as a footnote, but then when I looked at it, JS was the primary
target.

I was half hoping that Reason would fix some problems that keep me (and
probably many others from OCaml):

* Fragmented build tooling ecosystem with no outstanding options (ideally the Reason community would build a standard tool that improves on other options)

* Fragmented standard library ecosystem with no outstanding options (ideally the Reason community would standardize on a std lib, but this might be overly optimistic)

* Syntax (obviously this is Reason's target problem, but not the most important issue)

* Parallelism (well, Reason probably would never address this one)

~~~
nv-vn
I think it stands to fix the fragmented ecosystem by shear force. The masses
will decide what will become the de facto standard. For now, it seems like
jbuilder will be the winner.

------
RubenSandwich
This is a small nitpick but the line: "OCaml's compiler is pretty unique, it's
a set of pluggable parts that can be replaced and used together." is
inaccurate. Most modern compilers are broken up into backends and frontends
now, e.g. LLVM, JVM, .NET, etc.

~~~
thangngoc89
Hey author here,

I'll look into this and update the post accordingly. Thank you

~~~
RubenSandwich
No problem. Thanks for documenting the ReasonML toolchain and how it relates
to OCaml.

------
macawfish
Since a lot of people are coming to OCaml for the first time through ReasonML,
maybe this gotcha might be helpful:

I was having a really hard time doing `npm install -g bs-platform`. I kept
getting "linking" errors that I didn't understand, since I'm new to Ocaml. It
turned out that I needed to get rid of my ~/.opam directory. I did `mv ~/.opam
.opambk`, then `npm install -g bs-platform` suddenly worked!

Sweet! Looking forward to playing with ReasonML/OCaml!

~~~
jordwalke
Thanks for the tip. Also, we are working on making it easier to isolate opam
packages and npm packages side by side in one development environment so that
problems like this are avoided. This allows you to build a project that
depends on opam packages for build time tooling inside your JS projects. That
project is called esy, and it’s a young addition to the ecosystem but
something I’ve been using to greatly increase my own productivity for a while
now. It will not make BuckleScript compile opam packages (that is not
BuckleScript’s goal) but it will at least make the two ecosystems coexist
simultaneously.

~~~
macawfish
That's so important. Tooling can make or break a platform for me. I've tried
Haskell like 5 times and just never felt motivated enough to make it past the
various little issues that kept popping up.

So far OCaml seems like a bit of a smoother experience.

------
k__
Hopefully they'll get theit async story sorted out fast.

That's the only thing holding me back right now.

~~~
rehemiau
Could you elaborate on that? Do you mean async on frontend as in javascript
async/await or do you mean async on the backend as in threads etc?

~~~
k__
The first.

As far as I know OCaml and JS have stuff to handle this (lwt, promises, event-
loop etc.) but the usage in the "front-end" isn't so nice ATM.

------
jarpineh
I looked at ReasonML couple weeks back intrigued by Jared's post (referenced
in this thread as well) I noticed mentions about OCaml not supporting Unicode.
I was wondering what does that actually mean? If you target native you have to
find good external libraries for Unicode string manipulation? Or that text
handling in OCaml (and thus Reason) is harder compared to facilities in, say,
JavaScript and Python?

Other than that bit Reason React looks very promising. My usual use case tends
to start with arbitrary JSON source I'd like to build a tool for. Due to
strict typing this runs headlong into hurdles that have ended my
explorations...

~~~
laylomo2
What that means is that the language itself has no built-in constructs to
distinguish Unicode, or any other encoding by default.

OCaml's string type is more akin to an array of chars in C, in that it just
represents a series of bytes. There's nothing about the string type that
describes the contents of the bytes. So while you could put ascii in there,
when you to print the contents, it's up to the terminal emulator to decide how
to interpret those bytes.

One thing which you can do is include Unicode characters and save them in an
OCaml source file. The string type will capture the byte representation just
fine.

If you want to enrich the string type to also include format information, you
might have to look for other libraries.

And, one last point about the string type: traditionally the string type
allowed for mutation. In the last few years this behavior has been deprecated,
and in the latest version of Ocaml (4.06), a compiler flag -safe-string has
been enabled by default. This makes string immutable, and the traditional
behavior has been moved to a new type called bytes.

~~~
jarpineh
Thank you for this concise explanation. This doesn't seem insurmountable at
all.

------
gmfawcett
This is a bit of a tangent, but does anyone here know if there exists a JS
implementation of Ocaml's Graphics [1] module? I sometimes use Graphics for
quick-and-dirty native visualizations, and it would be kind of nice if there
were a straightforward way to re-purpose them as Web-based visualizations.

[1] [http://caml.inria.fr/pub/docs/manual-
ocaml/libref/Graphics.h...](http://caml.inria.fr/pub/docs/manual-
ocaml/libref/Graphics.html)

------
saosebastiao
How well does Reason interop with OCaml libraries? Also, how will it work with
upcoming changes in the OCaml language that require changes to the runtime
(like the multicore runtime, possibly modular implicits)?

~~~
bsansouci
Reason is merely a syntax change, it swapped the lexer and parser for its own.
The entire rest of the toolchain is the same, so once multicore happens,
Reason native will happily leverage it.

------
mlevental
started from quickstart and now we're here:

```

let message = "hello";

print_endline message; /* Prints "hello" */

```

output

$ bsb -make-world -w

>>>> Start compiling

Rebuilding since just get started

ninja: Entering directory `lib/bs'

[1/2] Building src/demo.mlast

FAILED: src/demo.mlast

/usr/local/lib/node_modules/bs-platform/lib/bsc.exe -pp

"/usr/local/lib/node_modules/bs-platform/lib/refmt3.exe --print binary" -w
-30-40+6+7+27+32..39+44+45+101 -bs-suffix -nostdlib -I
'/Users/max/dev_projects/my-first-app/node_modules/bs-platform/lib/ocaml' -no-
alias-deps -color always -c -o src/demo.mlast -bs-syntax-only -bs-binary-ast
-impl /Users/max/dev_projects/my-first-app/src/demo.re

File "/Users/max/dev_projects/my-first-app/src/demo.re", line 2, characters
15-22:

Error: 2122: syntax error, consider adding a `;' before

File "/Users/max/dev_projects/my-first-app/src/demo.re", line 1, characters
0-0:

Error: Error while running external preprocessor

Command line: /usr/local/lib/node_modules/bs-platform/lib/refmt3.exe --print
binary '/Users/max/dev_projects/my-first-app/src/demo.re' >
/var/folders/7_/ycch7zrn72b3r_f7sw8lp4v80000gn/T/ocamlpp5f8d7e

\---

this is straight from the docs. print_line(message) works fine.

~~~
thangngoc89
`print_endline message` is version 2 syntax. Could you point me to the exact
location so I can send a PR to fix it?

~~~
mlevental
looks like you found it already. somewhere else it said also that compiled js
is at lib/js. that's not true anymore (as i'm sure you know it's now at
src/name.bs.js)

~~~
yawaramin
Can you point to where you got that code from, a URL please. We will fix it so
that others won't get errors. Thanks for your help.

~~~
mlevental
print_endline was here but someone already got it:

[https://reasonml.github.io/docs/en/let-
binding.html](https://reasonml.github.io/docs/en/let-binding.html)

lib/js was here

[https://reasonml.github.io/docs/en/quickstart-
javascript.htm...](https://reasonml.github.io/docs/en/quickstart-
javascript.html)

but someone got that one too

~~~
yawaramin
Thanks! Appreciate the report :-)

