IMPERATIVE PROGRAMMING: how to execute code. Control flow as statements. “Algorithmic Programming”. Python and other OOP programming.
DECLARATIVE PROGRAMMING: WHAT to execute, not how. E.g. SQL, Excel. Functional programming is a subset of that.
The print function is a side effect. Reading from a file, write to a file, interacting with databases or APIs.
Side effects make code harder to maintain and test. It makes codes harder to isolate properly.
“pure function”: does not have side effects and only outputs based on its' input - no print calls, random numbers, datetime, etc. Easier to test (there will not be no “mock patch”).
Based on that, here are the tips from functional programming that can be applied to your code.
Use classes that have pure functions (methods), with no side effects inside of them.
Then, group the side effects into other classes or the main function - so they are isolated from the ones with pure functions.
The function must always return the same value for the same input.
Avoid side effects as much as possible.
Dataclasses have a “frozen” option, that turns them immutable.
That is also known as “higher order functions”: you can decompose them, pass to other functions and return another one.
You can use functools.partial
You can leverage immutable datastructures directly. Or instead of that, do not change a mutable datastructure: apply the transformations you need to it on a new variable.
Solves multithreading problems (multiple threads trying to change a shared variable)
Easier to understand and test
Only change variables when absolutely needed. Prefer immutability whenever possible.