Reason React 0.8
github.com
github.com
If this is your first time hearing about Reason, watch a video from its creator (Jordan Walke, creator of React) to learn more:
https://www.youtube.com/watch?v=5fG_lyNuEAw&t=11s
Fun facts about Reason:
- exports TypeScript! If you have a TS project and looking for some extra speed & stability, you don't have to sacrifice type safety interop
- It powers all of Messenger.com. The team put out a case study where they went from ~10 bugs a week to less than 10 a quarter by switching to Reason
- It uses the npm / yarn ecosystem so you can use your favorite / current packages without looking for something new.
ReasonML (OCaml) natively supports pattern matching, variants (Sum types), polymorphic variants, smart constructors, abstract data types, recursive types, and modules.
When you know how to use all of these features, you can prevent a remarkably large surface of bugs from ever compiling. As a new user, the first feature that will probably bring a smile to your face is pattern matching with variants.
If you are interested I highly recommend the book "Learn Type-Driven Development"
I used to use IntelliJ, and there was a solid plugin for that as well.
ReasonML's compiler is way faster than Typescript's.
In terms of compiler speeds, Draftbit has 1,000 ReasonML components and about 100 TypeScript files.
I can safely build AND type the entire ReasonML project before TypeScript returns the type results in watch mode.
But to answer your actual question: The current standard (reason-language-server) does simply wrap the compiler, and it's more than fast enough, but the community is working on a new merlin-based language server (ocaml-lsp) which does support partial compilation.
- Simple module system where you don't need to deal with named vs default imports and all the weird bugs getting them mixed up can bring
- TypeScript's inherent JS-like nature can pop up subtle bugs like forgetting to type a pair of parentheses:
function isSupported(): boolean {
return false;
}
function test() {
console.log(true && isSupported); // true
}
Or doing object/array indexing and forgetting to handle the case of 'undefined' because TypeScript doesn't enforce that. Or how any typings from before version 2 are suspect because they were written with the assumption that every type can be implicitly nullable. There are lots of these little footguns all over the place.- Higher-quality bindings: more stuff captured at the type level, you're not left to deal with bindings full of 'any', 'object', and 'function'
It's not even just about safety though. One of the biggest productivity drivers in Reason is its iteration speed–the compiler is so fast that you can try out changes basically as fast as you can save the file. And there are other things, like how all modules are implicitly available in scope, so you don't need to manage a 'wall of imports' at the top of every file before you can actually get to the code itself.
FWIW this was just fixed in TypeScript 3.9.
EDIT: I just tried in the TypeScript Playground (v3.9.2), it's actually rather worse than I thought, it prints not 'false' but the actual function itself as a value...
- It's Usable
- It Has Full Type Safety
Pick two.
I think the TypeScript is aware of the tradeoffs, have chosen the first two, and the result is a great developer/IDE experience for JavaScript programs (props!). Reason chooses the last two and creates a great experience for writing very safe web apps.
Edit: Apparently the functionality already exists as of 3.7. The update in 3.9 was to add it to ternary operations as well
Pattern matching has been by far my most favorite feature as someone coming from TypeScript: https://gist.github.com/peterpme/10840585ddced15a7f4ecd05394...
The ability to use "constants" that are inherently typed mean less mistakes and a better path forward for handling your application state.
Refactoring with this in mind, becomes a lot safer. For example, if I had a reducer that needed a new action, I would add that action to the `type`. The compiler would then tell me every place I needed to handle that case.
2."Implicit" Types (types that don't get in the way)
I don't need to type everything like I would in TypeScript. ReasonML already figures all of that out for me. I _can_ add the type if I want (for readability purposes). There is no such thing a `any` or any type of escape hatch for that (this can be frustrating at first) but once you get it, you write code more confidently.
3. React & Refactoring
Say I've got a bunch of React components I need to refactor. Reason types both the prop key and value. If I remove a prop or change that prop's data structure, I'll immediately know all the places I need to make that change.
I know some folks may roll their eyes when they read this, but after using both Reason and TypeScript at Draftbit, I strongly believe it's a competitive advantage. The stuff we ship in Reason just doesn't break.
But you do have to have the compiler give the thumbs up before it will compile the reason side of the project.
You can also checkout the tutorial for slowly converting a single file here, although I find myself doing this sort of thing very rarely: https://reasonml.github.io/docs/en/converting-from-js
I would add that the types from Reason are much "smaller" and concise, Option type or Result type and the immutability of Records/Objects creates an environment of safety that I don't have it in TypeScript.
TS fixes some of JSs issues, but many it cannot fix by still being a super set of JS.
Reason is similar (enough) to JS syntax-wise, while not having to deal with it's quirks. This is huge for me.
Did they move from Typescript or Javascript?
1) You called the 0.8 release "huge" in the release notes, even though it adds 11 new functions, removes 2, and updates 2 compared to 0.7, released a year prior. Is there something else about 0.8 that makes it larger than the sum of the API changes?
2) BuckleScript has seemingly been a one-man show for ~3 years. It is lagging noticeably behind the progress of the main OCaml project (including jsoo). ReasonML has a couple prominent contributors, but the overall (public) activity is dwarfed by Hongbo Zhang's work on BS. Is this because the ReasonML project is considered to be in a stable state, sufficient for production work?
2) BuckleScript's creator works for Facebook and has both a specific focus and a long-term vision for the project, more details here: https://www.youtube.com/watch?v=iWEQjvGGiTA . He also regularly blogs about ongoing improvements: https://reasonml.org/blog . Facebook Web Messenger and other products are heavily reliant on BuckleScript. I would consider that to be production-ready.
And Re: 2) I have no doubt that Mr. Zhang knows what he's doing. I was just noting how even after the prodigious amount of work he has put into BS over the years, it is still falling behind JSOO which has the benefit of being more tightly bound to the parent OCaml project. I know about the different tradeoffs JSOO and BS have made. All I meant to say is that one super-productive person is apparently (and understandably) not able to keep up with upstream (i.e. Inria + Jane Street + many others) in this case. And then we have the ReasonML project that has seen even less activity recently. If ReasonML in its current state is considered a finished product that requires minimal maintenance, I couldn't think of a better endorsement, to be honest.
"And then we have the ReasonML project that has seen even less activity recently"
You comment seemed to be based on the assumption that the Reason syntax is the sum total of the Reason project, and I provided examples that would adjust that frame of reference. See the high level goal I mentioned - bring fast development, fast running, fully type safe programming to the largest audience possible. Syntax is one important piece, but not everything, and it's not everything under the ReasonML project umbrella.
But surely you'll agree that "fast development, fast running, fully type safe programming" has been achieved years ago, and any incremental improvements coming from the BS project are just that - incremental.
Look, JSOO is great but it has a very different goal from BuckleScript: letting OCamlers use the Opam ecosystem to make frontend apps without caring about bundle size. And that's great, but it's not what JavaScript developers want.
Like I said, I know the tradeoffs between JSOO and Reason. And lack of features from the past 2~3 years of OCaml development is one of them.
2015 OCaml was an excellent language. 2020 OCaml is exquisite.
Yes, OCaml is older! Yes, OCaml circa 2015 is a useful language! But also, yes, OCaml has gained multiple useful features since 2015! In part because its development is driver by many, many people. And no, BuckleScript doesn't have some of those features as of May 2020! And it's not an indictment of Reason, but it is also a true statement that Reason/BS are lagging behind compared to what OCaml has to offer!
Fortunately, it's rather simple to see for yourself, you just need to head over to https://reasonml.github.io/en/try.html and try out some OCaml/Reason code and see what is emitted. In fact, the playground comes with various examples built-in, if you need some sample code to try out quickly.
I'm not sure what's driving you crazy about this interaction.
1. I would not classify this release as huge by most definitions, but I do think it is by a couple. First - it has many more contributors (both in code and on issues) than the 0.7 release and that means better reflection of community desires and direction. Second - it is the first release that forces 7.x BuckleScript which sets up ReasonReact for optimizations that would be impossible otherwise. Better support for `lazy`, `context`, and more.
2. BuckleScript is a true fork of OCaml and that comes with tradeoffs. On the plus you get JS interop you cannot achieve with JSOO (records and modules compiling to objects, https://bucklescript.github.io/blog/2020/03/26/generalize-un...). On the downside, active effort must be made and prioritized to upstream and maintain course with OCaml proper.
2a. Reason is being used in production at Facebook today, but Facebook also employs many of the people working on it. I personally consider it to be in a stable state for production use, but same as any technology I think it would be foolish to adopt Reason without better understanding the reason it exists, the problems it's trying to solve, and the drawbacks it has.
When they did that, I was running into numerous behaviour bugs on Messenger.com. Anything from weird image uploads to link previews not showing up in one chat but working in another etc.
Reduction in pure code bugs is nice and all, but a very synthetic and useless metric overall IMO.
I'm wondering, will there be more marketing for Reason or Reason React after it reaching 1.0?
I found when introducing this kind of technology for day jobs, people either get confused or concerned usually, even though it really looks like React now.
It seems to be very hard to have programming languages taking off without marketing nowadays because the adoption usually comes from other people's adoption. It's the "threshold of immortality" of programming languages according to Simon Peyton Jones.
You get a lot of optimizations for free with react-redux. Given reason-react now supports hooks you can also just use `useReducer` but this lacks some optimizations.
Edit The gap between https://redex.github.io/ and type.d seems like a challenge
Now? Writing a binding is barely a speed bump, but when I first started writing Reason code it definitely tripped me up a few times. I tried to make the road behind me a bit smoother [1], but that gap you observed is real.
But as someone who writes/reviews both Typescript and Reason, pretty much every day, there is space for both projects, so I don't see that gap as being relevant to the survival of Reason--rather, its something that with hard word will be improved over time.
Can anyone recommend some up to date ReasonReact & ReasonML tutorials & books?
Also, what is the recommended architecture - are there any good starter projects?
A good intro (at least for me, since I'm into videotutorials) is https://egghead.io/courses/get-started-with-reason.
I'm really considering ReasonML for my app, however I'm not a big fan of the styling in reason react.
Just to clarify and sell a little my ppx, styled-ppx supports the css prop as well, many people prefer that over the component api.
https://github.com/ahrefs/bs-emotion seems to be more mature. styled-ppx is built on top of it (seen within styled-ppx readme)
At Draftbit we've been using https://tailwindcss.com with @dylanirlbeck's https://github.com/dylanirlbeck/tailwind-ppx with great success!
We also use `bs-emotion` (which on the styled-components vs. emotion api side is the same)
I'm doing great progress on it and don't want to miss something that is crucial for you.