loading...
Cover image for A Reason to Code

A Reason to Code

kayis profile image K ・4 min read

A few months ago I read about a new programming language called Reason. It was sold to me as a better JavaScript, like so many compile-to-javascript languages were. We've seen them, CoffeeScript, LiveScript, Elm, ClojureScript. So I was a bit reluctant to look into it, but a few days ago I started reading into it and I was blown away.

What is Reason?

Reason is a language that can compile to JavaScript and native, like you know from C/C++. So you can use it to write a Node.js application, or your front-end or write a normal native app, like people did back in the days ;)

The interesting thing about Reason is now, it's not completely new. It can basically be seen as a new syntax for OCaml. So you can convert Reason to OCaml and back without any losses.

Why a new syntax? Well, I guess the target group of Reason are web developers, so they wanted to make it look more like JavaScript.

For example JavaScript has spread syntax for arrays:

    const x = 1;
    const a = [2, 3, 4];
    const b = [x, ...a]; // -> [1,2,3,4];
Enter fullscreen mode Exit fullscreen mode

Doing this with OCaml looks like that:

    let x = 1
    let a = [2; 3; 4]
    let b = x :: a
Enter fullscreen mode Exit fullscreen mode

Doing this with Reason looks like that:

    let x = 1;
    let a = [2, 3, 4];
    let b = [x, ...a];
Enter fullscreen mode Exit fullscreen mode

How does it work with JavaScript?

The OCaml compiler has a plugin-system you can implement your own back-ends for it that create the outputs you need. So devs at Bloomberg build BuckleScript, a back-end for the OCaml compiler that outputs JavaScript.

Now, people weren't too impressed by this, because, as I mentioned above, many languages did this before, also OCaml didn't have a too familiar syntax, but the creators of Reason found that the OCaml compiler is pretty gud and wanted to harness this power for the Web, so they set out to create this new syntax while trying to get full OCaml compat.

So what happens is, you write Reason, convert it to OCaml (lossless) and compile it down to JavaScript with the help of BuckleScript. As far as I know it's one of the fastest to-javascript compilers out there and it even produces human readable code, which is funny since it compiles from OCaml byte-code to JavaScript.

Why should anyone care?

OCaml is crazy powerful.

First, it has a sound static type-system, that gives really nice error messages, think Elm level errors, with thinks like "you wrote X did you mean Y?", but yes, some people don't care much about this and those who do already using Elm, Flow or TypeScript. (btw. Flow is build in OCaml)

Second, implicit imports and exports for modules. You know the whole bunch of imports we got now in JavaScript? If you don't fold your imports with an IDE, the more complex JS files today show a list of imports and you have to scroll down to see the real code. Also, often we forget to import something and everything blows up. OCaml does all this for you. Every .re file is a module and exports all its top-level variables.

    /* MyModule.re */
    let a = 1;
    let b = 2;
    {
      let notExported = 3;
    }

    /* MyOtherModule.re */
    let a = MyModule.a;
    let b = MyModule.b;
    let c = MyModule.notExported; // -> error
Enter fullscreen mode Exit fullscreen mode

Third, OCaml figures out what values it can calculate at compile time and does dead code elimination. This is like tree-shaking on steroids. Prepack tries to do this for JavaScript.

For example this Reason code:

    let z = {
      let x = 10;
      let y = 20;
      x + y
    }
Enter fullscreen mode Exit fullscreen mode

Could naively be converted to this JavaScript:

    let z;
    {
      const x = 10;
      const y = 20;
      z = x + y;
    }
    exports.z = z;
Enter fullscreen mode Exit fullscreen mode

But it's actually converted to (something like) this:

    var z = 30;
    exports.z = z;
Enter fullscreen mode Exit fullscreen mode

It throws out modules you don't use, since you never import them yourself anyway, OCaml does it for you and then it also tries to pre-calculate values and throws out dead code.

Finally, it has ESLint and Prettier (which is inspired by refmt, the Reason formatter) like features already included. Code hints and automatic formatting, so you don't have to think about indentation or semicolons anymore.

Bonus, it even has a JSX-like syntax, which is a big win for React developers and it's even a bit more light weight than JSX.


    // JavaScript JSX
    <Component key={a} ref={b} foo={c} d={d}> {child1} {child2} </Component>

    // Reason JSX
    <Component key=a ref=b foo=c d> child1 child2 </Component>
Enter fullscreen mode Exit fullscreen mode

Also, there are some smaller things that help in everyday coding, like named function arguments or the use of the type-system instead of strings for decisions, things that compile down to a bool or number in the end instead of using strings etc.

Conclusion

Reason seems to be a pretty interesting piece of software. It addresses a bunch of things I see in my daily JavaScript coding, which gives me the feeling that it's a practical language. I didn't think like this when I heard that it's basically OCaml -> a functional programming language.

So I think it is worth a try, for my private projects at least.

Discussion

pic
Editor guide
Collapse
yawaramin profile image
Yawar Amin

Great article! Just one small nitpick: BuckleScript compiles a typed OCaml AST to JavaScript; there is another compiler called js_of_ocaml (JSOO) which compiles OCaml bytecode to JavaScript.

Collapse
kayis profile image
K Author

Ah, yes, this makes much more sense :D