Actually answer to this is pretty simple, but not short.
What, if anything, should a modifier return? Should it not return an indicator of success/failure? Should it instead return nothing, but throw an exception upon failure?
First you have to ask yourself why you should not return anything from command (modifier). What we gain by that?
There is actually one advantage worth it - we can run that command asynchronously in a background, i.e. put command that creates new post to command queue, that is handled by other process, maybe written in another language.
By that you can just put command to queue and return http response immediately not waiting for post creation to happen, big performance gain, right?
Don't mistake returning value from command and returning http response. You must do the latter to inform client that putting command to queue was successful or not, but only that.
Raising exception from command is the same as returning value, so you cannot do that.
Now is the question, how to return id of the newly created post to client, because we want to let user edit that post immediately.
So, commands doesn't have return value, ok. But they have result, an effect.
In example if call
turnLightOn command it doesn't return true or false to indicate that it worked - it's silly, but we can see with our own eyes that lights are on and we can see at night. That is an effect of command.
How do we represent effect in programming? By events of course.
Command that turned lights on, also publishes event
LightsTurnedOn (past time) and client is subscribed to that event.
Going back to our post creation example:
Should constructors be treated as modifiers (is the creation of an object a side-effect)? I suspect not, since a constructor that created an object but didn't return a reference to it would be pretty annoying.
Side effect is everything that is not referential transparent.
It means that if your constructor does nothing else, but only returns reference to newly created object, then there is no side effect.
But if that constructor uses global values (get or set, doesn't matter) to create that object, then it's not referential transparent and it has side effect. Why?
self.bar = config.BAZ
foo1 = Foo()
config.BAZ = 'something different'
foo2 = Foo()
foo1 != foo2