"The ideal number of arguments for a function is zero" is plain wrong. The ideal number of arguments is exactly the number needed to enable your function to be side-effect free. Less than that and you needlessly cause your functions to be impure thus forcing you to steer away from the pit of success and climb the gradient of pain. Sometimes "Uncle Bob" is spot on with his advice. Sometimes he is spectacularly wrong. His zero arguments advice is an example of the latter
(Source: comment by @David Arno under another question on this site)
The comment has gained a spectacular amount of 133 upvotes, which is why I'd like to pay some closer attention to its merit.
As far as I'm aware, there are two separate ways in programming: pure functional programming (what this comment is encouraging) and tell, don't ask (which from time to time is being recommended on this website as well). AFAIK these two principles are fundamentally incompatible, close to being opposites of each other: pure functional can be summarized as "only return values, have no side effects" while tell, don't ask can be summarized as "don't return anything, only have side effects". Also, I'm kind of perplexed because I thought that tell, don't ask was considered the core of OO paradigm while pure funcitons were considered the core of functional paradigm - now I see pure functions recommended in OO!
I suppose developers should likely chose one of these paradigms and stick to it? Well I must admit I could never bring myself to follow either. Oftentimes it seems convenient for me to return a value and I can't really see how can I achieve what I want to achieve only with side effects. Oftentimes it seems convenient for me to have side effects and I can't really see how can I achieve what I want to achieve only by returning values. Also, oftentimes (I guess this is horrible) I have methods that do both.
However, from these 133 upvotes I'm reasoning that currently pure functional programming is "winning" as it becomes a consensus that it is superior to tell, don't ask. Is this correct?
Therefore, on the example of this antipattern-ridden game I'm trying to make: If I wanted to bring it to conformance with pure functional paradigm - HOW?!
It seems reasonable to me to have a battle state. Since this is a turn based game, I keep battle states in a dictionary (multiplayer - there may be many battles played by many players at the same time). Whenever a player makes their turn, I call an appropriate method on the battle state which (a) modifies the state accordingly and (b) returns updates to the players, which get serialized into JSON and basically just tell them what has just happened on the board. This, I suppose, is in a flagrant violation of BOTH principles and at the same time.
OK - I could make a method RETURN a battle state instead of modifying it in place if I really wanted to. But! Will I then have to copy everything in the battle state needlessly just to return a wholly new state instead of modifying it in place?
Now perhaps if the move is an attack I could just return a characters updated HP? Problem is, it's not that simple: game rules, a move can and often will have many more effects than just removing a portion of a player's HP. For example, it may increase the distance between characters, apply special effects, etc etc.
It seems so much simpler for me to just modify the state in place and return updates...
But how would an experienced engineer tackle this?