This is entirely true, concurrency is hard and hiding it away is not helping anyone. The two abstractions that work really well are monads and CSP (channels and share-nothing threads).
However, at least when using Python, it's not always an option to only use concurrent code. Many useful libraries rely on blocking APIs and greenlets are more predictable than threads and cheaper than both threads and processes.
Not even Go gets this right: goroutines share memory implicitly! There are few real options: Clojure+core.async, Haskell, Erlang. Python+Twisted or similar would also be an option, but it's annoying to write and means you have to ignore most libraries out there, at which point you might as well use a better language in the first place.
"One, in particular, involved a brass, mechanical cockroach which would crawl around on a timer, leaping out of a player’s hands if it was in their inventory, moving between rooms if not. In the multithreaded version, the cockroach would leap out of your hands but then also still stay in your hands. As the cockroach moved between rooms it would create shadow copies of itself, slowly but inexorably creating a cockroach apocalypse as tens of thousands of pointers to the cockroach, each somehow acquiring their own timer, scuttled their way into every player’s inventory dozens of times."
OK... if the state was this bad, I'm willing to go out on a limb and lay the blame on the people writing the code. "Threads are hard" has become somewhat of a truism in the industry but seriously, they're not this hard.
Programming is hard, algebra is hard, heck, plumbing or wiring a building is hard. And yet, competent people who've studied the skills, practiced their craft and are willing to spend time and effort in carefully working through each project, manage to build working, lasting systems in all sorts of complex fields. Concurrency is hard and there's no silver bullet. Let's not pretend the Next Cool Thing will suddenly make all the difficulties disappear.
However, at least when using Python, it's not always an option to only use concurrent code. Many useful libraries rely on blocking APIs and greenlets are more predictable than threads and cheaper than both threads and processes.
Not even Go gets this right: goroutines share memory implicitly! There are few real options: Clojure+core.async, Haskell, Erlang. Python+Twisted or similar would also be an option, but it's annoying to write and means you have to ignore most libraries out there, at which point you might as well use a better language in the first place.