10

I recall a principle that a professor talked about while I was in school (back in the mists of time) that went something along the lines of "A method/function should either orchestrate other functions, or perform small, a specific task", but I can't for the life of me remember what the formal name of that principle is, beyond being a super-symmetric application of the Single Responsibility Principle.

Anyone know the name?

3
  • 1
    Seperation Of Concerns? Level Of Detail?
    – Kain0_0
    Commented Mar 2, 2021 at 0:44
  • "...these questions aren't educational in any way, because there's no way to learn about the process of discovery. A particular community member, by virtue of their experience in the field, just happens to be able to take the limited information you remembered and fill in enough of the blanks to guess the correct answer... guessing game questions do not meet our goal of making the Internet better." (blog.stackoverflow.com/2012/02/lets-play-the-guessing-game)
    – gnat
    Commented Mar 2, 2021 at 18:32
  • 1
    @gnat - I'm not worried about getting the specific term I'm thinking of, I'm trying to find an acceptable term that I can teach my juniors that will provide them with commonly accepted grammar. Communication is a meaningful part of the work we do.
    – Garandy
    Commented Mar 2, 2021 at 19:44

4 Answers 4

16

There is a principle that makes you do this but it doesn’t say it the way your professor did.

Every function orchestrates other functions. Even adding two numbers together and assigning them to a variable is orchestrating functions. You can twist yourself in knots thinking this way.

The single level of abstraction principle up holds the spirit of that idea but doesn’t require that you pretend you know where the bottom is. It only requires that you set a level of abstraction and stick with it.

That means this is not structural. It’s conceptual. It doesn’t matter if you mix functions from your own code, a library, or even the basic language functions.

What matters is that when you mix them together they don’t yo-yo your brain up to hand waving high abstraction and down to low level details all within the same function.

Do that and you’ll end up separating orchestrating and doing just fine.

1
  • "Even adding two numbers together and assigning them to a variable is orchestrating functions". I guess it depends on a programming language and on definition of a "function". In many languages neither assignment not operators are functions, so the distinction is quite clear. No need for knots. Commented Mar 2, 2021 at 18:37
3

You may be thinking of Command Query Separation (CQS). It doesn't exactly relate to "orchestrating" vs "doing", but if this is from "back in the mists of time", maybe this is what you meant.

An excerpt from the Wikipedia article:

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. More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.

Thus, the point is not only to focus on one job, but also to avoid mistaken modification while attempting to read data.

2

There's a principle called "do one thing and do it well" which may be related.

There's also the distinction between "pure function" (also called a "computation" or "calculation"), versus an "effectful procedure" (also called an "instruction" or "statement"):

  • A pure function only returns a result (that is its 'externally observable behaviour'). It may arrive at that result directly, or by calling other pure functions. Examples include performing arithmetic, branching on some data, constructing some new value, etc.
  • An effectful procedure will change the system in some way. Examples include printing some output, communicating with some external system (e.g. a database), changing the value of some externally-visible variable, etc. If a function returns an uninformative result, like void in Java, that's a good indicator that it's performing an effect (since there's no other reason for such a function to exist!)

It is a good idea to do as much calculation as possible using pure functions, since it is almost always 'safe' to call a pure function from anywhere in our code, without affecting any external system or any other part of our program (modulo edge cases like overflowing the stack). In contrast, we must be careful to only perform effects when it is safe to do so; for example, imagine calling a function to calculate some number, and it happens to also close a network socket! Effects can also alter the way other parts of our program behave, e.g. assigning a new value to a variable might alter the branches taken elsewhere in the code.

If a function/method does both of these things, i.e. performing some effects and returning some calculated result, it is said to be "impure". Such effects are called "side effects", since we may just want to do the calculation, but end up causing unintended effects as well.

This distinction appears in approaches like "ports and adapters"/"functional core, imperative shell"/"hexagonal architecture" and "pure functional programming".

0

Perhaps a better statement would be to say that a function shouldn't control flow and perform tasks. I don't know the formal principle behind it, but I usually use this technique in my own code.

void check() {
    if (dispensing) {
        checkDispensing();
    } else {
        checkNotDispensing();
    }
}

Then the sub methods would actually perform the tasks.

My $.02.

2
  • I would call that a general guideline and one possible way to split up methods more so than a rule to be strictly followed (which applies to most of programming anyway). If, for example, checkDispensing just consists of a single line of code that isn't used anywhere else, then having a separate method for that probably just makes the code harder to understand and maintain. What is and isn't "perform tasks" probably also isn't that clear. You'll almost always use some library to access a DB or files or whatever, in which case the library's methods are arguably performing the tasks. Commented Mar 2, 2021 at 14:56
  • @BernhardBarker Yes. Even if that library is <stdio.h>.
    – bdsl
    Commented Mar 2, 2021 at 15:12

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