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?

Garandy
  • 211
  • 1
  • 7
  • 1
    Seperation Of Concerns? Level Of Detail? – Kain0_0 Mar 02 '21 at 00: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." (http://blog.stackoverflow.com/2012/02/lets-play-the-guessing-game) – gnat Mar 02 '21 at 18:32
  • @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 Mar 02 '21 at 19:44

4 Answers4

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.

candied_orange
  • 102,279
  • 24
  • 197
  • 315
  • _"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. – Andrew Savinykh Mar 02 '21 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.

TheRubberDuck
  • 933
  • 6
  • 13
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".

Warbo
  • 1,205
  • 7
  • 11
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.

Thom
  • 109
  • 3
  • 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. – Bernhard Barker Mar 02 '21 at 14:56
  • @BernhardBarker Yes. Even if that library is ``. – bdsl Mar 02 '21 at 15:12