All software are about functions operating on data. Data come with the concepts of structure  and state; concepts of functions include prototype and implementation. We can change data structures at coding-time and change data states at run-time. But the prototype and implementation of a function cannot be changed at run-time, they are allowed to be changed at coding-time only. Another different is that data are passive while functions can access data and/or call other functions. These differences between functions and data should be carefully considered when designing software.
Regardless of programming paradigms or languages, a good software design must be easy to maintain and upgrade with a little effort of changing source code. In my opinion, in such a good design:
- Calling functions in a hard-coded manner / using hard-coded data values should be RESTRICTED.
TheClass.theStaticFunction("This is a hard-coded string");
is an example of hard-coding. As we see, the actual implementation and value of the called function and used data are totally known at coding-time and could not be changed at run-time. These should be restricted because the only way to change hard-coded things is changing code.
- A function should NOT depend on too many data/functions. This aims to minimize the likelihood of changing source code of that function. Indeed, when a function depends on many other data/functions, it will be easily affected by a small change in those other data/functions. Moreover, a function with too much knowledge is an indication of the violation of Single Responsibility Principle.
- A function/data X should NOT have too many dependent functions. This aims to minimize the impact of changing source code of X; because when it changes, all the dependents will change also.
In the case #3, if X is a function, the problem might be mitigated. As long as the prototype of X is untouched, we are free to modify its implementation without bothering the dependents. But if X is data, that’s a big trouble.
Firstly, at coding-time, changing a data always means changing its structure, no any other choice. This is not the case of a function where the change can be about either its prototype or implementation. Secondly, at run-time, if an instance of X is being used by many functions, its state is likely to be changed by those functions. It’s very difficult to control the state of an instance when the number of its dependent functions is high. Reusing one or some of these functions is not easy since they may expect a certain state of the instance before executing.
Object-oriented Programming (OOP) addresses this trouble by putting data and their dependent functions together into small units so-called objects. Functions of an object cannot access data of other objects; calling function of other objects is allowed but in a limited way; clearly, this aims to reduce arbitrary dependencies which should be avoided as much as possible. If you have a big object, or publish your object data, or use static functions; you will lose the benefits of OOP and your code may be not OOP anymore even you are using a language that supports OOP.
Functional Programming (FP), on the other hand, does not hide data like OOP, but advocates immutable data and pure functions. No — or minimal — state change is a quiet attractive characteristic of FP.
OOP and FP solve the problem of data in different ways. While OOP hides data (good) but lets data be mutable (bad), FP exposes data (bad) but prefers immutable data (good). Thus, it would be great if we can combine and apply all of these good principles when programming and don’t care too much about whether the adopted paradigm must be either OOP or FP.
No matter your adopted programming paradigm, the principles and practices of good software design still apply. You can still create a good design even with Procedural Programming, but you can also create a bad design with OOP or FP. Programming paradigms give you useful disciplines, but that how you apply and follow those disciplines is another story.
 Even a simple int number still has its structure: the 4 bytes.