If you’ve ever experienced the following, you would benefit from adopting a type system.
- After fetching a list of data you may find that a certain field doesn’t exist on one of the records, causing the app to crash unless explicitly handled.
- An instance of a class you imported doesn’t have a method you’re trying to invoke.
- Your IDE doesn’t know what methods and properties are available, so it cannot easily assist you with autocomplete.
- Difficulty reasoning about code, type systems at a glance make it easier to refactor
Flow, TypeScript, or ReasonML
Let’s say you have an existing codebase that you wish to make bulletproof. With respect to type errors, you could try adopting Flow or TypeScript — they have a fairly similar syntax.
On the other hand adopting one of these in a large, existing codebase is difficult. You would have a backlog crammed with tasks relating to creating types and interfaces with code that made not have been designed in a type friendly way.
On top of all of this, Flow and TypeScript do not offer 100% type safety in their code.
Reason accomplished perfect type safety through inference, and makes annotating variables and function signatures much more straightforward.
Simple and Clearly Contrived Examples
Consider the following code:
1let add = (a, b) => a + b;
1let add = (a: number, b: number) => a + b
Allow me now to expose this gradual typing with a contrived example.
1let add = (a: string, b: number) => a + b2add('some string', 5) // outputs: "some string5"
That function works! This is absolutely preposterous! Now how does Reason handle this?
1let add = (a, b) => a + b;2add("some string", 5);3/*4This has type:5 string6but somewhere wanted:7 int8*/
This function was flawed at the implementation level. Reason has different operators for int, float, and string addition.
The purpose of this contrived example was to show that it is still very possible to have odd type “errors” even though it wont break the application.
In a pure Reason program, developers will not have to deal with productions bugs that have to do with types or null values.
One of the neatest features of TypeScript is the enhancement you get in code editor suggestions & autocompletion.
This is one area where TypeScript has a leg up on Reason, because a TypeScript program doesn’t need to compile perfectly in order to offer autocompletion. Reason makes you fix errors in syntax or types before it gives you helpful autosuggestion.
This is the case on VSCode, but I know many Reason developers use vim. I cannot answer for the level of support each editor has.
Even though I am a big fan of ReasonML, I have built production applications with TypeScript or Flow and I enjoy them as well. The wave behind TypeScript makes it especially good to pick up these days, considering there is plenty of writing and community support behind it.
Reason on the other hand is harder to pick up because there is comparatively less writing and content behind it. Through blog posts like this, I am hoping to change that.
If you have some interest in checking out Reason, I’d start with the docs here. Also, be sure to follow people like @jordwalke, @jaredforsyth, and @sgrove on twitter. They are pretty knowledgable with respect to the ReasonML/OCaml ecosystem.
If you want to how ReasonML works seamlessly with GraphQL, check out this article I wrote on ReasonML with GraphQL, the Future of Type-Safe Web Applications.