ReasonML with Phoenix?

I know @OvermindDL1 is really into BuckleScript, but has anyone tried Reason? It’s built on top of BuckleScript but perhaps has a nicer syntax. I’m thinking about strapping it onto a project soon.

For those interested, here is a cool tutorial for Reason and React https://jaredforsyth.com/2017/07/05/a-reason-react-tutorial/

5 Likes

Ooo you’re inviting a bikeshedding here :wink:

I’m actually liking OCaml syntax. Reason’s let run () => doSomething looks kinda weird compared to OCaml’s let run () = do_something. But Reason is arguably getting more traction so I have to accept that more and more libs are written in its syntax (they should be interoperable though).

Since Reason also uses BuckleScript’s bsb for compiling, I think @OvermindDL1’s guide is still relevant?

I’m not an ML guy, so I can’t see any syntactical difference between those two snippets. The only difference I do see is snake_case vs. camelCase, which is usually not syntax, but just convention, especially since you say, both can interoperate, I do assume, that neither of the compilers enforces one of those styles.

So could you please show some pieces of code that actually do differ in syntax, not only in conventions?

It is all those hipsters without proper education in how syntax should
look like and want to force everything into looking like javascript or
ruby or whatever.

Wait… Which forum is this now again? :wink:

5 Likes

In the examples I provided, there is also a difference between = and =>. Actually, in Reason, let run () => doSomething is a sugar of let run = fun () => doSomething.

This is a bit confusing for me since Reason is conflating = in function assignment and -> in pattern matching into =>. For example:

In OCaml

let num = 42

let add x y = x + y

let maybe_do_something value =
  match value with
  | Some x -> do_something x
  | None   -> None

In Reason

let num = 42;

let add x y => x + y;

let maybeDoSomething value => {
  switch value {
  | Some x => doSomething x;
  | None   => None;
  }
};

Reason is more Javascript-y and arguably noisy with brackets, fat arrows, and semicolons. However most are really minor preference issues which I think I can live with.

A difference so small that I wasn’t able to see it anymore after I have seen that casing thing :wink:

But, yes, I do understand your issue now. In a functional language, where functions are just plain data, there shouldn’t be any difference in the way how one assigns a name to them.

In the switch/match example you gave though, I do not think that it makes any difference if it is a fat or a slim arrow, both can be read as “implies” easily in that situation.

1 Like

Indeed, as I said I regard them as minor cosmetic issues :slight_smile:

The game changer with Reason is definitely tooling, though. I’ve heard stories that Facebook really pushes for DX. I think it’s kinda like when Elixir comes along with Mix and Hex, making it pleasant to start developing. The target market, JavaScript developers, is also contributing to the high adoption rate, probably since they are so used to trying new libraries and frameworks every few weeks or so ^^

Bucklescript as the Reason/OCaml -> JavaScript compiler is also blazingly fast, very nice to work with.

Going by the syntax alone I prefer Bucklescript/OCaml :slight_smile:

With regards to Reason itself (and aside from why anyone would want to make something more like JS - with it’s (Imo) horrible syntax!) I generally steer clear of facebook tech - I just don’t like the company or what they stand for.

What kind of tooling does it have that Bucklescript doesn’t? And are the Bucklescript community catching up?

3 Likes

Me too!

Actually, most tooling that Reason brings can be used for OCaml (fortunately). For example, they have:

  1. BetterErrors, to prettify OCaml’s default error message to a more Elm-ish style helpful errors.
  2. reason-tools, a browser extension that does several nifty things, including prettifying OCaml’s documentation, translating between Reason-OCaml code, and easy codebase navigation on GitHub.

A few that are Reason-specific would be refmt (opinionated code formatter, inspired by gofmt for Golang, which in turn inspires prettier for JS) and rtop (their REPL, but OCaml also has utop). More on these toolings here. refmt is probably the only one that’s missing for OCaml (aside from ocp-indent which does only indentation).

They lately also have been announcing better support for ReasonReact (writing your React apps in Reason via BuckleScript bindings). It should also be able to be translated to OCaml. Theoretically all Reason code can be called from OCaml (I think), but as Reason is getting more marketing, most newer code is written in Reason so you would inevitably need to understand it too to embrace the whole landscape. FB is doing great in increasing adoption so far (but haven’t affected you, I see, @AstonJ :smile:)

One thing that’s lacking in Reason at the moment is support for native programming (in contrast to targeting JS). It’s still a work in progress.

Do note that I’m also still in my early stages of exploring both of these and haven’t build anything meaningful, but that’s what I understand so far. @OvermindDL1 should be able to give more detailed explanation. :smile:

1 Like

Thanks Bobby. That just leaves me with one question - why didn’t they just support Bucklescript? :confused:

1 Like

I don’t think I could give a definitive answer for that… but if I have to guess: they do it for the purpose of marketing and adoption. AFAIK FB has deep roots of OCaml in their codebase, for example in creating their Hack language and Flow type checker. I assume they are very comfortable with it, but perhaps they don’t see OCaml getting adopted without some, um, “interventions”, hence Reason.

I’m concluding this based on the major selling point on their website, which is the new, “familiar” syntax over OCaml. Their main target is JS devs, and nothing draws people faster than familiarity, however superficial (e.g. Ruby to Elixir). Adoption drives contributions, so I guess they’re also hoping to get as many hands as possible to improve the OCaml ecosystem overall.

1 Like

I think my excitement isn’t really the syntax per se its the rapidly growing ecosystem. I want to use React and GraphQL, and the support isn’t there yet in BuckleScript, but Reason has React support and I’m looking forward to GraphQL. The tools look nice, especially the formatting. I’m also excited that I might be able to get JS devs to use this.

1 Like

Bucklescript is an OCaml back-end to output Javascript.

ReasonML is a new syntax that transpiles to OCaml.

ReasonML comes with Bucklescript and Bucklescript comes with ReasonML. :slight_smile:

Big time! I do not like ReasonML’s syntax personally. ReasonML’s sole purpose was to make OCaml more approachable by Javascript dev’s by adding things like braces and such annoyances when there was no purpose. And I would not say Reason is getting more traction, OCaml is still significantly larger than ReasonML by far. But even then you do not have to choose, you can mix and match them all you want in the same project, they end up the same thing after all.

Precisely yep.

What he was showing there was reason uses => instead of = for binding/assignment, which is friggin weird I still find.

However the full list of syntax conversion between the two is at: https://facebook.github.io/reason/mlCompared.html

A quick example between the two, here is a function in OCaml:

let doStuff a b =
  let c = a * 2 in
  let d = c + b in
  d * 4

And in reason:

let doStuff a b => {
  let c = a * 2;
  let d = c + b;
  d * 4
}

It is not a big difference between them, just I find ReasonML more verbose.

ReasonML does include built in a JSX processor, but that is just a normal PPX and you can add it to normal OCaml code too. ReasonML was designed to be entirely interoperable AND most nicely is that it include a tool called refmt (also included with bucklescript) that will not only reformat both reason and ocaml code, but it can also translate between them transparently back and forth all you want (there is even a browser extension that embeds it so you can convert reason and ocaml code back and forth on web pages too). Quite literally ReasonML is just a bit of a syntax change over ocaml, nothing big, and there is a LOT more documentation on the OCaml syntax out for sure.

/me coughs

@bobbypriambodo did much better examples yep.

And to note, in OCaml this:

let add a b = a + b

Is just short-hand for:

let add = fun a b -> a + b

Which is just short-hand for:

let add = fun a -> fun b -> a + b

^.^

Yep, also another note, the ReasonML parser knows nothing about types, so it cannot by definition change how the language works in any way, shape, or form, it is purely syntactical.

Most of ReasonML’s tooling is just Bucklescript’s tooling, which is fantastic. The only other tool that Reason adds of it’s own is refmt, which is a converter between ReasonML and OCaml anyway, which is indeed quite useful. :slight_smile:

That is not a Bucklescript thing, that is just how the OCaml compiler works, it is one of the, if not the fastest optimizing compiler in existence for any language, it is a very model of efficiency and readability both. The OCaml compiler is awesome and amazing. :slight_smile:

I’m not big on the company or what they stand for either, but I have to admit they make very well made tools. Tools that should not necessarily exist (ReasonML seems so much like Fluff to me, and Flow, as awesome as it is, is just fixing a deficiency in JavaScript that should not have existed to begin with).

Bucklescript has the entire OCaml ecosystem tooling to start, in addition it also embeds the ninja build processor to control the OCaml compiler, which makes compiling a single line call, and also has templates for doing things, like, making a new project (I still need to make such a template for a bucklescript-tea project). Really the only extra tool ReasonML has over Bucklescript is really just refmt.

Actually BetterErrors is a normal OCaml library, it makes errors prettier, ReasonML is just including it by default.
The reason-tools is the browser extension I mentioned above, thanks for the link!

Yep, rtop is just a skin over utop, it does not really add anything.

ocp-indent is nice but yeah, not a full formatter. refmt can reformat ocaml code too, not just ReasonML, and Buckelscript includes it too already. :wink:

OCaml and ReasonML translate directly, nothing special, even the JSX stuff is just a PPX that you can use from normal OCaml too. :wink:

As it converts to OCaml directly you can just feed it through the normal OCaml compiler instead of Bucklescript, that is not hard at all to do.

I talk with the devs quite often for both Bucklescript and ReasonML both so I know both quite well if anyone has questions. :slight_smile:

Because they are two different things. Bucklescript is just a plugin to the OCaml compiler that outputs Javascript instead of native code. ReasonML is just a syntax shuffler to OCaml, entirely different levels and purposes. :slight_smile:

I think Elm and Purescript and such really helped give the normal ML syntax visibility to Javascript, without those I’d see ReasonML being more useful, but really it is not nowadays.

Precisely, it is just to give a skin on top of OCaml that is more javascript’y, it is also heavily in flux too, like they are making a PR right now to make function call syntax be add(a, b) instead of add a b, but of course they will translate between those transparently in any case. ^.^

Uh, I have to ask what? React is just a library, the bindings to it are normal OCaml external declarations, and those bindings can be used from OCaml or ReasonML both, so what are you talking about that reason has react support but bucklescript does not? What sense is it to say that ‘bucklescript has react support’ when bucklescript is just the back-end for the ocaml compiler that outputs javascript, the bindings are what the support is, not the bucklescript backend nor the reasonml syntax formatter. Plus anything that works in ReasonML works in OCaml and anything that works in OCaml works in ReasonML, they are the same language in the end with different skins.

3 Likes

What do you mean ODL? What is a syntax shuffler :lol:

  • Bucklescript - let’s you write OCaml but outputs JS.
  • ReasonML - A bit like Bucklescript but with JS’y syntax that transpiles into OCaml.

?

Please elaborate :lol:

As in it does not know ‘what’ it is doing, it just does things like ‘Convert ; into in’ and such things. It builds an AST, but it has no typing information, no context about what it is doing, it is very very simple.

Nope, it does not let you write OCaml, it only adds the back-end pass. It is still the normal OCaml compiler.

The OCaml compiler you can think of like a Plug pipeline in Elixir/Plug/Phoenix, the top of the ‘plug’/pipeline is text, it passes that text to a parser to output ast, which is then passed to a typer that adds type information to the AST, that is then passed to multiple layers over optimizers that optimize the AST, which is then passed to a backend ‘plug’, OCaml by default comes with 2 back-ends, one is native code (near as fast as optimized C++) and the other is a byte-code interpreter (think the BEAM or the JVM, almost no one uses it anymore as the native code is so much substantially faster).

Along that entire pipeline you can add in more layers. Like the PPX (a compiler plugin) for JSX adds in syntax like <blah a=bloop /> and that layer converts it into something like blah ~a:bloop, or a PPX like yojson that takes attributes like [@derive yojson] and takes the record it is attached to and auto-generates json’ing and unjson’ing functions, or you can have something like CAML4P at the top of the pipeline that takes in CAML4P syntax and translates it to OCAML syntax for the OCaml parser right after it, or lower in the pipeline to, for example, add a new backend.

ReasonML is just a plugin just like CAML4P (a popular OCaml plugin for making DSEL’s), it takes ReasonML code and converts it to OCaml that takes it right after.

Bucklescript is lower level, it adds itself near the end of the pipeline where a lot of typing still exists and outputs the AST as javascript (then halt()'s like an Elixir Plug halt’s).

The compiler is entirely pluggable and it is actually very easy to make plugins for it (I have one that kind of outputs some Elixir but I have no time to work on it currently, later though). :slight_smile:

Literally different levels of the pipeline as described above. :slight_smile:

3 Likes

Ahh, I phrased that poorly. I’m interested in the built in jsx support(albeit thin), and the docs they’re putting together for using React with Reason. I may find that BuckleScript and by extension OCaml do everything I want, but I’m excited to see a big company putting money and dev hours into the ecosystem.

Ah yeah as mentioned in my above post, their JSX stuff is just another PPX that you can include or not include as you wish, just like any other PPX, it is not ReasonML specific in any way, shape, or form and works fine with even plain non-bucklescript OCaml (since bucklescript is just a back-end after all). :wink:

Yeah, I wasn’t aware previously that the JSX integration wasn’t specific to Reason.

1 Like

I think the biggest thing for me, is that I showed this to a few JS devs, and they got it and seemed to see the benefit.

1 Like

Those are the people that ReasonML was designed specifically for, the JS devs that know not many/any languages. ^.^