The most important part of coding I would consider would be abstraction. When designing in Java or other OOPs it is heavily considered to design your code base in such a way that there is proper abstraction or it could cause lot of issues. A single class should have a single responsibility and it should not allow other classes to mess with it. It should only provide the needed information also in a manner that the class could be changed with another implementation without any of the other classes knowing about this. The next important part would be for the developer to know at what STATE the program is. If the program has moved from STATE A to STATE B this should be because the developer wanted it to happen not because of some side effect. This exactly what happens when we allow mutation. There will be millions of states our program can enter into without our own knowledge. This will make it hard to track down bugs since we wont even know how it moved from one state to another (ReactJS with Redux solves this same problem where each of the state the application goes into is tracked)
Erlang is a language that comprises all the good practices of coding and they provide only the essentials. They don’t allow the developer to go beyond these practices as the authors of language have rightly assumed, if there is a shortcut that can be taken then our evolutionary human brain always takes the easiest path and messes up the code. Erlang used to have mutability to it and the authors of the language analyzed it causes lots of bugs (which as we all know it really does) and removed it from the language
I guess another major cause of issues that is caused in our programs is mutability. When we are allowed to mutate a state from multiple locations then eventually we cant keep track of what are all the state our program can go into. We humans are not smart enough to magically understand all the infinite states that can occur when you allow mutation in your code. Accept we are dumb, dont allow mutation. This will allow us to predict and keep track of how many states our program can go into and how they can go into them. When we write a code then we should be able to say what are all the possible states the program can go into and there should no side effects that can happen to our code due to change of state in some other part of our application. When you give 2,2 as parameter to your add() function in no circumstance should it return value based on the state of the application. It should always invariably be 4. Though it might feel obvious, think of how many functions we would have written that will never follow this simple rule. Next time you write a function remember it this way f(x,y) -> x + y. This is the function in math, you wont expect this function to return value different based on the state
Think of writing a application as writing state machines*. Consider we are running 100s of state machines that interact with each other. Since state machines can always let us know what series of steps led the program to eventually end up at that particular place which caused the crash, we can easily reproduce it. Erlang makes this really really easy for us.
Each Java thread costs us 2MB in memory that means if you run a thread pool of lets say 10000 threads, boom, you get out of memory. This without doing anything not a single variable assigned a value. A thread costs us 2MB in memory. Where as process in Erlang takes a mere 16bits so you can run millions of process in your same VM without a problem. (Coroutines in Kotlin is also said to be really lightweight but it comes with same problems of mutating values in memory which is not possible in Erlang.)
And another beauty of process is you can communicate between processes only using protocol. This is a common problem in language like java where you mutate the state from one thread and it causes a crash in another thread. Since mutation is anyway not allowed in Erlang this is avoided. But also the beauty of using protocols to communicate between process is it can allow you to structure your code in such a way that each separate process can be considered as its own service in a micro service architecture and you are communicating between different micro services. What is the use of this? Lets say one of your process crashes then you can easily start it back (since it is not state dependent) without causing rest of your application to follow it. You will also think more carefully when writing the program since Erlang will make you do so, Your process/service will have separation of concern and single responsibility.
Why you should look into Erlang development? Erlang is the secret sauce that made Whatsapp scale to millions of users in a single server. There are stories that say that a application written in Erlang has been running for 21 years with 0 Downtime. It is functional language (learning to code in functional language is like learning to drive a car. We developers have been driving 2 wheeler(OOPs) for too long. Try a functional language it makes you feel like you don’t know anything about coding. Just the same feeling when you try to drive a car first time. It is totally alien and gives you broader perspective with respect to coding)