In OCaml 4, all threads shared a global lock, similar to Python’s GIL, and lots of existing code depends on this lock for thread safety.
So OCaml 5, instead of simply removing the lock, introduced a new abstraction, domains, which are pools of one or more threads sharing a lock. Thus, legacy code keeps spawning multiple threads within its domain, sharing a lock, while new code can spawn new single-thread domains instead, which are effectively the same as having lockless threads.
There’s still some discussion about whether the older thread abstraction is still valuable or not for new code and which should be the focus[1], but either way I think this was a better path than Python’s arduous attempt to remove the GIL altogether.
How did we get domain-local storage before thread-local? ↩︎