Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

So here's some perspective on the concurrency problem. I write network servers for a living - most are in C++ or Java, but I would love to be able to use Python.

There are a number of high-level approaches you can use to concurrency. Shared-nothing processes. Threads and locks. Callback-based events. Coroutines. Dependency graphs and data-flow programming.

They all suck, and they all suck in different ways. Processes have large context-switching overheads, and take up a lot of memory, and require that you serialize any data you want to communicate across them. Threads and locks make it very easy to corrupt memory if you forget a lock, very easy to deadlock if you don't have a clear convention for what order to take locks in, and ends up being non-composable when you have libraries written under different such conventions. Callbacks require that you give up the usage of "semicolon" (or "newline") as a statement terminator; instead you have to break up your program into lots of little functions whenever you make a call that might block, and you have to manually manage state shared between these callbacks. Coroutines requires explicit yield points in your code, and opens up the possibility of a poorly-behaving coroutine monopolizing the CPU. Dependency graphs also require manual state management and lots of little functions, and often a lot of boilerplate to specify the graph.

Python has a "There should be one - and only one - obvious way to do things" philosophy, and with asyncio, Guido seems to have decided that the obvious way for Python is going to be coroutines. It's an interesting choice, and he's not alone in that - I recall Knuth writing that coroutines were an under-studied and under-utilized language concept that had many desirable properties. Coroutines free you from having to worry about your global mutable state potentially changing on every single expression, and they also give you the state-management and composition benefits that explicit callbacks lack.

There are parts of them that suck - like having to explicitly adds "yield from" at any blocking suspension point, and having to propagate that "yield from" down the call stack if added to a synchronous call. But having written a bunch of threaded Java server and (desktop) GUI code, a lot of callback-based Javascript, and a lot of C++ in both callback and dependency-graph style, all of those models suck a whole lot as well.



Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: