The human mind is a remarkable thing. When you think about all of the subconscious things that happen concurrently, you can’t help but be humbled. Now, my daughter can’t always walk and chew gum at the same time, but that’s another story entirely. The mind is typically up to the challenge. Computers? Well, that’s another story.
In Seven Languages in Seven Weeks, I found several different approaches for concurrency.
Scala and Io used actors and a few other constructs. It’s a well-reasoned, practical approach that’s proven.
Erlang’s approach was perhaps the most dramatic. Creating a thread is a very lightweight process. Also, monitoring and messaging are so simple (Erlang also uses an actor model) that you find yourself creating new threads that respond to messages. Sound like an object? In many ways, Erlang threads can act like them. Mutable state is greatly minimized, and only allowed through specialized constructs. And when a thread fails, the monitoring systems are so strong that you can just let the thread crash and start another one. The approach gives you reliability to the extreme.
Clojure’s memory model is also revolutionary. It uses an approach called STM, or Software Transactional Memory. (Other concurrency constructs like agents, promises, and futures are also available.) So for the most part, you avoid mutable state. When you really need it, you use STM in the context of a transaction. We’ve designed databases that way for years, and the system works.
Haskell takes the most extreme approach, relying on pure functional programming. You can simulate imperative style programming with a feature called monads. They are a mathematical abstraction that can be used to simulate stateful programming by capturing a series of functions that mutate state. It’s interesting and powerful stuff.