In this article, I will cover my migration progress between all three languages and explain why and what brought me to move over.
I hope I will shed some light and convince some of you to try out a new language for the sake of your software and its reliability.
Eventually, as you grow up you will start to develop bigger web applications and those become more complex, so you will turn to a framework like Angular, Vuejs or Reactjs.
Because the language has been essentially written for web browsers initially, the language is built to always work as long as browsers support the standards of the language. This basically allows a website written in the 1990s to still work today in your fresh new Chrome version, even if the code that was written is basically 30 years old.
That being said, if you do write an application for a web browser, odds are this app will be functional forever.
The problem with that is, that it crashes, and it crashes in the worst way: Runtime crashes. This means, it’s your end users that discover those errors, not you.
How using Typescript solve some of those issues
Typescript is capable of a few things as of version 3.2, such as :
- Protect you from possible null or undefined objects
- No unused parameters or variables
- Verify the integrity of your conditions and if you have properly checked an object for a certain state
Such things will prevent minor errors, and the compiler will catch those issues for you. You should get fewer runtime errors if you can hand-out the job of checking those type of issues to Typescript.
Relying on the compiler is a really good thing for your code, as if you change something elsewhere, it will snowball and Typescript will start to warn you about a potential error.
Typing variables allow Typescript to identify if the object or variable is of the right type.
let n: number = 0; n = “a”; // Typescript will not allow that, as this is attempting to convert a number type to a string.
Using types across your code allow the compiler to know more about your code and help you out. This will ensure that your code is properly maintained and follow strict guidelines for better predictability of the functionality.
This is a very simple and generic example, but as your application grows, you eventually run down in those simple errors because things get out of control. If you can rely on the compiler to protect you from those errors, then you will have a lot fewer runtime errors.
The bad parts of Typescript and why I moved to Elm
You are held responsible as a developer to seek external modules to help you out with things like bundling, state management, minifying, etc.
We run a pretty elaborated NodeJS server all written in typescript where I work, and we use advanced types and enums all over the place in order to ensure we are as safe as possible, and it works okay. We have all the strict flags on, making sure our code is as strictly typed as it can from Typescript perspective.
It provides insight, protect us from many pitfalls and increase the confidence we have in our app, but the language does not enforce those standards, we have to maintain them manually, and that is an issue when someone new comes and does not follow those standards out of the box.
Typescript also allows you to cheat, using the
any type, you can basically skip all type check and tell typescript that a certain piece of code can do anything. Those are very easy to use when you don’t want to comply with the system and many use that as an easy exit door to get their feature done faster.
Typescript does not protect you from side effects, which affect state mutability. I’ve had several hard to track issues with Angular and React causes by data mutability.
So what is Elm and how or why is it better than Typescript?
Let start with one thing: Elm is a functional language, and if you have never touched one before, this is going to be a big step going in.
Elm guarantees that you will NEVER get a runtime error.
It is a language that once data is in its system, nothing can ever be in a state of null or undefined. Things will always have a value, and the system will never crash because things have their proper type as well.
Elm comes with
Data Immutability right out of the box,
Minify code for you, and most importantly, it
Enforces type safety, preventing developers to try and cut corners. It is very fast and very lightweight.
If you are concerned, the output can be embedded in any web page easily, so it’s not that hard to get started with a small trial if your project is immense (You don’t need to convert all your code to elm to embed it).
It has an advanced typing system that allows you do to even more, which I will cover entirely in another blog post.
Because elm is a functional language, you cannot get into a weird state caused by side-effects and your code is very easily testable. Functions you write will always return exactly the same result given the same input data.
Because you can so heavily depend on the Elm compiler, updating and refactoring pieces of code is an absolute breeze. The compiler will complain for quite a bit of time, but the moment it stops from doing so, you are good to go. No need to test anything, simply follow the compiler guidance about each error he finds and your code will all start working again once you have done so. This experience really gives you a good confidence level in your software even after destroying it apart and rebuilding it. (Which normally, you would be unsure if you have missed something somewhere)
The Elm Architecture (TEA)
Elm has what it calls its own architecture that some project is based on (Redux). It’s very pleasant to work in TEA, things are straight forward and a lot easier to manage. It does an extremely good job at separating the logic from the rest, which comes in nice when testing your code.
Because the language is built that way, all developers are forced to follow that pattern and to be strict about anything they create. There is no such thing as
any in elm, and thus, every contributor is forced to properly write code. The result is quite simple: Better code, better maintainability, no runtime errors.
Elm will force you to handle all the cases all the time, which in a way, has a strain on you as a developer, but a good one. If you do an API call as an example, then you must handle the cases of
Loading, but the end result is that all those handled case will give not only a better understanding of what is going on to the user but also no errors in case something bad happened (which you might not normally write code to cover that case in Typescript).
The hard part going into Elm
Coming from a background of C++, C#, Java, Typescript, Python, I am more than used to write loops (While/For) and when you get to a functional style language, there is no such thing. You must use functions such as
Filter and more, and that is how you manipulate your data when you want to loop. I found it hard initially to get used to that.
The result is amazing when you start to understand how it all works. You become a lot more efficient going back in an older project and applying those principles.
Elm is a completely different language, it took some time to learn it and you will have to work hard as well to understand the new keywords and patterns of that language. A good place to start is at ElmProgramming.
Writing Encoders and Decoders initially are a complex task and feel long to do, but it’s because of those that elm is capable of ensuring your data is always safe and validated before going into the elm machine. The compiler is capable of ensuring input and output data are always safe because of those. You must take the proper time to learn how to create them and use them.
Elm does not allow you to save anything by yourself. You do not create variables. You simply pass back your whole new model and elm takes care of saving that model for you in memory (Because that is an unpure method to do). This was for me, hard initially to grasp because I was used to keeping data in a class as a class parameters (a private variable as an example). This makes it so that you only have one state that is saved, and that state is your main model, which you can manipulate and change the way you want it. It’s just, hard to change your way of dealing with code.
Give it a shot, upgrade your codebase to a language that will help you along the way
I will be honest, I have never had so much fun writing code. Elm is just very well built, and building a web app with this language makes the job a lot more enjoyable to do.
We push updates to our online cloud platform on production on a daily/weekly basis, and that is not a big deal for anybody. If the compiler compiled your code, you know, nothing is broken. Run some tests, and we are good to go to deploy that code.
The only errors you will get in Elm are going to be logic errors, but those are caused by you, the developer who did not think his things right.
I hope this will help some developers move along in their code and use better languages/tools to support their web apps in a more reliable and enjoyable way.
☞ Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)
☞ The Web Developer Bootcamp
☞ Understanding static in React and possibly future versions of JS
Originally published by Kevin Lanthier at https://medium.com