Decades ago computer processors were designed with just one core. At that time, it made sense to program without thinking about the distribution of tasks across processing cores.
Most programmers did not care if they were using the full potential of the processor to perform tasks in parallel. However, after much research in this sector, processors have evolved, and now they have several cores! Today, these processors are known as multicore and are very common, even in mobile handsets.
Nevertheless, even in our modern and constantly evolving scenario, many programmers continue to write code in the classic way, without considering that it is now possible to achieve much more from the processors by processing several tasks in parallel and, thus, increasing efficiency.
There is an attempt to solve this problem using different computer languages, but the implementation is, in general, very complicated, and, in the end, it does not truly solve the problem.
Object-oriented systems have to deal with state mutation in parallel processes, and checking those states when you have multiple cores competing in the same memory space is a recipe for disaster.
The excellent book Elixir – Do Zero à Concorrência (by Tiago Davi – only available in Portuguese at the moment) explains how the Elixir programming language solves this problem very well. Elixir is an immutable language that uses the functional paradigm. Elixir allows us to think in terms of functions and data transformation. Elixir is also based on processes that communicate in isolation; therefore, it does not suffer the undesirable side effects of other languages. Instead, it potentially creates a fresh, clean version of the data for every possible mutation. Elixir runs code in small processes, each with its own state, which makes the construction of distributed and competing systems in natural, transparent, and easy.