Proposal: Command Syntax

GetUserInfo adds a deliberate point of confusion. It calls/queries via fetch. But this instance of calling/querying should not be confused with the "query" of CQS. They are related but different. This is unequivocally a command. It is a command because it uses an external endpoint whose results, given the same arguments, may vary based on when it's called.

That function would be invoked getUserInfo!. using command syntax:

  • queries — always pure, never mutating
  • return-nothing commands (!) — impure (side effecting) with no return value
  • return-something commands (!.) — impure (side effecting/ed) with a return value

Yours is that last flavor. As I read CQS on Wikipedia I realize even the writers there have a note of confusion.

[CQS] states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer.[1] More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.

By their own definition commands "perform actions" and queries "return data", as you inferred. But then they get into "referential transparency" which is founded on the purity aspect. So the terms command and query as used appear to be more synonymous with pure and impure than putting and taking once you arrive at their own conclusion.

The interesting aspect of your sample function is how it shows commands must sometimes return a value. Therefore, it is clearer to say that a command can be side effecting (causing) or side effected (impacted by side effects caused elsewhere), as with your function. Still, it reinforces all three use cases are valid, at times.

The syntax is optional and people can use or not use it, just as with type annotations. Although the syntax adds a useful semantic that goes beyond just syntax (e.g. fluent interfaces for commands), it's for those who want to distinguish between pure and impure, safe and unsafe—especially since doing so makes code easier to understand where the actual side effects come into play.