Edit based on responses so far
I am starting with an edit so as to save future contributors from going down the same path others have.
I am only interested in contributions that stick to the exact definition of SRP I have quoted below. So no “you can think of SRP as…” type elaborations, as that takes away from the objectivity.
—
First, a bit of background to give more context to the question.
To keep the discussion focused, I will only be talking about classes here, not functions, or modules, or any other construct. So where you read any of these other constructs, think 'class' instead.
The definition
Let's start with how Robert C. Martin (Bob) puts it:
The Single Responsibility Principle (SRP) states that each software module should have one and only one reason to change.
He goes on to say:
When you write a software module, you want to make sure that when changes are requested, those changes can only originate from a single person... Why? Because we don’t want to get the COO fired because we made a change requested by the CTO.
As a side note, if anyone is to be fired here, it's the person who decided that unit tests were not required - ensuring nothing is broken following a change is exactly the 'concern' of unit-tests run on the pipeline.
Back to SRP...
I find it pragmatically impossible to always adhere to it, and unless I am mistaken, it certainly appears to be what Bob is intending we do; apply it everywhere. Sure there are some classes where you can easily implement this pattern. In fact the typical marketing done in favour of SRP would use examples like "Report generator should not also format a report" and so on... Sure. Agree. Easy. Why wouldn't you separate out those two pieces of functionality!?
But think of other very-common situations you are likely to encounter during development. For example, writing a websocket client. Here's a sample implementation: https://learn.microsoft.com/en-us/dotnet/api/system.net.websockets.clientwebsocket?view=net-7.0
It lets you connect AND disconnect AND read AND write AND other stuff. Clearly it (along with a thousand other classes across .Net and other runtimes/frameworks) violates SRP.
Bob describes change in terms of "actors", which when talking about a class, boils down to consumers of that class.
With a websocket client, there might be some parts of your program that only need to read from it, while others need it for writing. A change request from one part can have a bearing on another part, so based on the definition of SRP (I urge you to pause and read the Edit at the top), the websocket client violates SRP.
Now, you may be inclined to argue that the websocket client can be thought of as self-contained, bounded, a singular entity, or some such. However these are all concepts relating to SoC, not SRP (as per its definition), and I would urge you to refer back to my edit at the top once again.
Finally, the question:
Is there anything beyond SoC (Separation of Concern) that SRP provides? If so, it would help to provide an example, that clearly describes a problem not solvable using SoC alone. Preferably something with minimal code and realistic, so no God class or such that you really ought not to be doing anyway as a developer.
Ref: https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html