13

I read once that a method should either have a return value (and be referentially transparent), or have side-effect(s), but not both. I cannot find any references to this rule, but want to learn more about it.

What is the origin of this advice? Out of what person or community did it arise?

Extra credit: What is the claimed benefit of following this advice?

5
  • 1
    @gnat Yes, it is primarily about history. I feared that the extra credit part was too subjective to stand on its own, and that history stood a better chance of escaping closure. I'll add the tag. Jul 16, 2015 at 18:51
  • some of the answers that pile on made me wonder whether you ask about benefit that was claimed by an author of this advice or for a list of all benefits that are possible to claim at all?
    – gnat
    Jul 16, 2015 at 19:10
  • @gnat I ask about the benefit claimed by the author (again, fearing closure), but I sure don't mind the pile-on reasons--they're answering the question I actually wanted to ask. If I were to remove "claimed" from my question, making the pile-on answers on-topic, would that push the question too far into the subjective? Jul 16, 2015 at 19:14
  • "pile-on reasons" are likely to push the question to be closed as too broad. If you prefer it "to stay on the open side", I think it would be safer to narrow it down to benefit that was claimed by author
    – gnat
    Jul 16, 2015 at 19:17
  • One benefit is that if you're paid by volume of code, this produces extra. "doSomething; GetResultOfSomething; HandleErrorsFromSomething;"
    – Ⴖuі
    Jul 27, 2015 at 21:04

3 Answers 3

13

According to Greg Young, this idea originated from Bertrand Meyer: Command-Query separation.

It 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.

1: Eiffel: a language for software engineering slide 43-48

In Domain Driven Design, this is similar to Command-Query-Read Separation/Segregation (CQRS), as named by Greg Young.

Greg Young took the idea of CQS from Bertrand to name CQRS as mentioned by Martin Fowler in this CQRS article

Benefits

  • The Read (Query) part can be scaled/tweaked differently from the Write (command) part. Separating the two would prevent either from getting in the way of each other when optimization/performance is key.

Read the article in the Martin Fowler link for more.

3
  • 1
    Naturally, in many situation generating a useful result and doing some modification at the same time is no more expensive than the doing the harder of the two separately. Jul 16, 2015 at 20:07
  • 1
    @Deduplicator A cliche example being InterlockedCompareExchange?
    – Ⴖuі
    Jul 27, 2015 at 21:09
  • 1
    This advice obviously doesn't apply when the return is some information about what was done in the command, however - a method to remove rows from a dataset can pretty much change the dataset state, removing the indicated rows according to a given criteria, and then return the number of rows removed or even a list with said rows.
    – T. Sar
    Aug 11, 2017 at 13:10
4

I don't know where it comes from, but it is good advice and fairly straight-forward to understand.

Any sanely designed program will be broken up into various parts, combined and composed in various ways. The harder it is to reason about what any particular part does, the harder it will be to make sure that your program will react in a predictable manner.

Isolating the parts that produce side-effects makes the rest easier to reason about, test, and debug. Reducing the number of side-effects in each part that does generate a side-effect will make that part easier to work with in the same manner.

If you decompose it even further, a return value is an effect. Side-effects are an effect. A function should only produce 1 effect (if possible) because the greater number of inputs and effects a function has, the greater the difficulty in reasoning about what it actually does.

4
  • this doen't even attempt to address the question asked, see How to Answer
    – gnat
    Jul 16, 2015 at 18:43
  • @gnat My question came in two parts: The main question ("who"), and the extra credit ("why). Doesn't this address the extra credit part? Jul 16, 2015 at 18:50
  • per my reading ("claimed benefit"), why-part is expected to be one proposed by the author of the quote. Question doesn't appear to be asking for a list of all possible benefits
    – gnat
    Jul 16, 2015 at 18:53
  • 2
    @gnat I understood the question as an attempt to understand this advice, both the reason behind it as well as the context in which it was given. I don't believe that it was inappropriate to address only part of the question.
    – Morgen
    Jul 16, 2015 at 19:47
1

Extra credit: What is the originally claimed benefit of following this advice?

One of the benefits of separating return value from side effects is that it removes a potential problem which may be caused by short-circuit evaluation.

bool FooWithSideEffect() {
    // do query
    // do side effect
    return resultOfQuery;
}

bool BarWithSideEffect() {
    // do query
    // do side effect
    return resultOfQuery;
}

void BadShortCircuitEvaluation()
{
    // the programmer's intent is to have side effects of both functions
    if (FooWithSideEffect() && BarWithSideEffect() ) {
        // do something
    }

    // in case FooWithSideEffect() returns true, 
    // then BarWithSideEffect() is not called at all
    // because of short-circuit evaluation
}
3
  • is this a benefit claimed by author of the advice?
    – gnat
    Jul 16, 2015 at 19:09
  • @gnat I have mixed-up historical and practical, I fear. Jul 16, 2015 at 19:11
  • 1
    the comment and code do not match, BarWithSideEffects is not called if FooWithSideEffects returns false
    – jk.
    Jul 28, 2015 at 9:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.