Concurrent programming is one the oldest and hardest issues in the Computer Science Book. For years, we have been using locks, big threads sharing the minimum, using optimistic reasoning for “how data will be updated”. And we are still stuck with the same issues of some part of the code “failing” to use the updated object, dead and soft locks with hard-to-see origins, and many many crashes.
Some languages found some means around it. Rust uses reference ownership to ensure no-concurrent write-access to some object. Haskell (and other purely functional languages) uses persistent/immutable data-structures. immutable.js takes the second approach.
By having immutable datatypes, many operations are safer, as you can pass collections around without defensive copies and you can expose these publicly without having to ensure that the user can modify its state. As you are unable to “update” such an object, you’ll have to think about how state is updated throughout the code. It can be weird at first, but it enforces a well defined separation between producers, transformers and consumers of data. It results in clearer programs, easier to dig into and less likely to crash.
This library is quite simple in essence. It exposes the usual suspects: Map, List & Set. You can add and remove a value on an instance, yielding a new collection each time. Each of them is based on ECMAScript classical interfaces, but functionally oriented: you can map, filter, zip as wanted. To avoid the cost of creating a new collection every time, it tries to reuse most of the originating collection. Equality check is also faster on average, as it doesn’t need to check the whole chain of values, but stops at the first common reference found. It might be a bit cumbersome at first, because it forces to check for nearly all corner-cases, such as an empty list (`get` returns `T|undefined`), but it ensures that no exception happens at runtime. Overall, it reduces the potential for error directly at the type level.
We can do it in JavaScript today, bridging a gap between an unsafe language and functional paradise. Let’s go down this path to safer, better, faster, stronger programs.