> To me, this is akin to the pure/unpure function classification in FP, it makes sense that calling an unpure function would also "taint" the caller.
Since this could be read in a very abstract, purist way, I'd like to add that this is also very much an architecture concern for many pieces of code.
At work, I regularly encounter issues with a piece of code that is written in one of the worst imaginable spaghetti styles. And, since it changes things in a database (not even in proper transactions, btw), and is written to pretty much prevent being tested, no one wants to touch it.
Yet, what the code does would really match an "FP" approach:
- Read in all inputs. You might even read during computation if you're simulating FP through transaction isolation
- Compute the outputs and the new desired state
- Pass that to someone who writes it back to the database and commits the transaction
Outputs in our case are messages that get stored in the database, too (in order to allow recovering after transmission issues), so "output" in effect also just means "state". You don't always have to read "FP" in the strictest sense -- there's a spectrum to this.
Now, if that code was written in such a way it would be easily testable and thus refactorable. In fact, most ideas in the clean/hexagonal architectures or "functional core, imperative shell" are to achieve exactly this. But since the author of said code never had any pushback, they just kept making an already grim situation worse with every change. For years.
I see the same issue with the "ice nine" argument for async. If async infects all your business logic, chances are your abstractions suck.
Edit: Also note that goroutines do effectively the same thing as synchronous code in a larger asynchronous function call: You group the code you can sensibly do in one go into a single goroutine. Then you pass the result to someone else to perform the next step.
So, it's very often just another way to express the same process. CSP will invariably be a better abstraction for some problems, and async/await for others.