What is a program?
Program is a code. A text. How text may wear out?
Have you ever heard about a mathematical theorem that was replaced with a new one? Or, maybe, about a mathematical function becoming obsolete?
Once proven, a mathematical idea is correct forever.
Programs must be same. But, they are not. Why?
The short answer : a lack of mathematics (and abstraction) in modern programming.
Now, let us sort it out.
Speed bigotry
Machines become obsolete, we are inventing new technologies and ways of production. Software becomes outdated with its target hardware. But, why does it have target hardware? To work as fast as possible, to exploit as much implementation details as it may reach. A small abstraction level would bring loss in speed, but give independence from hardware. Written once, used forever.
Program or programmer : one must die
Well, we have C# and Java, that have abstraction layer over hardware. So, they would be good to write programs once and use forever?
Yes, they could be...but.
We don't really need programs that would work forever.
Try to imagine that. 99% of software engineering would become pointless. All those C# and Java developers would lose their jobs.
Fortunately for them, they have OOP. Software killer.
OOP was invented bad for a purpose. We are killing our software constantly, because we are getting paid for programming new software.
Eventual death for any program is essential for us, otherwise we would have no money.
How does OOP kill programs
Classes are perfect for making code rigid and useless.
Perfect example -- you may meet such classes as Vector2, Vector3, Matrix3, Matrix4, Quaternion in any library, related to computer graphics or mathematical modeling.
Why don't everyone use only one best implementation, like everyone does with int, float, char, byte? Answer is simple -- primitive types are not classes.
They were designed once to be used forever, and you can't achieve such design level with classes.
Classes are designed to make program "disabled" everywhere, excepting limited purpose, that is demanded by current moment.
OOP is about resolving thousand times the same problem, implementing brand new (one more bad) solution.
Way out
Well, let us imagine, how would look an immortal vector implementation? First, it must have no mutable state. Same as string, int, char. You can't mutate them, you can only create new.
And, we already have such vector implementation in Lisp (Clojure) :
(let [
v [1 2 3] ; same as (vector 1 2 3)
[x y z] v ; vector deconstruction
]
(println v) ; [1 2 3]
(println x y z) ; 1 2 3
)
So, we don't need classes. More than that : we don't even need to declare functions to calculate dot product, or vectors sum, or transposed matrix :
(let[
a [1 2 3]
b [4 5 6]
c (apply + (map * a b)) ; a and b dot product
d (mapv + a b) ; a and b sum
e (vector a b) ; 3x2 matrix from a and b
f (apply mapv vector e) ; transposing matrix e
]
)
There is no OOP, code is simple, flexible and it will never face necessity to be edited. Written once, used forever.
Does not fit for business
I frequently hear, that functional approaches do not fit for business. That OOP is only one and best choice for software design.
Well, there is a particle of truth. OOP is truly best choice for business, if you ask programmers. And, it is a deadly mistake, if you consider interests of business itself.
Do you want to pay programmers for doing same job hundred times? Or you want them to resolve actual business problems?
Choice is clear.
Top comments (4)
Thanks, I really enjoyed reading.
But I did not really get why we cannot create vector class (or struct) with OOP once and forever. What about dozens of several entities in dotnet BCL, aren't they written once and forever?
Classes from dotnet BCL, or Java JCL, do violate OOP principles, and, frequently, they are just data structures, though even for them, from time to time, programmers write special implementations.
Idea of object is a union of data and functions.
Looking on vector classes as example, we may see, why it is a mistake.
System.Numerics.Vector
is an immutable class, whileSystem.Numerics.Vector3
is a mutable structure. Both of them have separate sets of functions, though those functions do the same.Data must be separate from function, otherwise function is bound to the data type.
In Lisp vectors do not have such functions as
mul
,sum
, ordot
, vectors are collections there, and such functions asmap
,concat
,reduce
, and many of others are applicable on vectors and other collections as well.Data type is temporary, function code is eternal. Coupling function with data type, we make our program temporary.
Ok clean functions appear to be more resistant to change, but anyways they use data structures as arguments and return values and use data structures internally, so once the data structure is changed the function will likely need to be updated.
That is completely about language means and approaches.
In C# functions may be generic, coupling only with interfaces (or delegates).
Following good design, we won't face necessity to edit our function.
In case with dynamically typed languages everything is much easier -- usually type checks are not welcome there.