This commit is contained in:
Miloslav Ciz 2024-03-01 12:59:58 +01:00
parent ebde14dd84
commit 4c419f1fa0
10 changed files with 1714 additions and 1692 deletions

12
oop.md
View file

@ -4,7 +4,7 @@
Object-oriented programming (OOP, also object-obsessed programming, objectfuscated programming or artificial inelegance) is a [programming paradigm](paradigm.md) that tries to model reality as a collection of abstract objects that communicate with each other and obey some specific rules. While the idea itself isn't bad and can be useful in certain cases and while pure OOP in very old languages like [Smalltalk](smalltalk.md) may have even been quite elegant, by later adoption by [capitalist businesses](capitalist_software.md) the concept has been extremely twisted and degenerated to unbelievable levels -- **OOP has become extremely overused, extremely badly implemented and downright forced in programming languages** that nowadays try to apply this [abstraction](abstraction.md) to every single program and concept, creating [anti-patterns](anti_pattern.md), unnecessary issues and of course greatly significant amounts of [bloat](bloat.md). [We](lrs.md) therefore see the OOP of today as a **[cancer](cancer.md) of programming**. OOP was basically a software development fashion wave that scarred the industry for decades, it has poisoned minds of several generations. Nowadays despite OOP still keeping many fans the critical stance towards it isn't even controversial anymore, many others have voiced the criticism over and over, usually the most competent programmers like [Richard Stallman](rms.md) and [Linux Torvalds](torvalds.md) and groups like [suckless](suckless.md) and [bitreich](bitreich.md). Ugly examples of OOP gone bad include [Java](java.md) and [C++](cpp.md) (which at least doesn't force it). Other languages such as [Python](python.md) and [Javascript](javascript.md) include OOP but have lightened it up a bit and at least allow you to avoid using it. You should probably learn OOP but only to see why it's bad (and to actually understand 99% of code written nowadays).
**A [real life](irl.md) analogy** to give a bit of high level overview: the original [Smalltalk](smalltalk.md) style OOP was kind of like when society invented [democracy](democracy.md) -- a simple idea which everyone understands (we are 10 cavemen, let's just vote on stuff mkay?) that's many times useful and works well, e.g. on a scale of a village or a small city. Then cities grew bigger (just as software did), into states and empires and the idea kept getting more and more complicated -- people just wanted to keep the democracy, apply it to everything and scale it indefinitely, but for that they had to add more complexity, they implemented representatives, parliaments, senates, presidents, vicepresidents, ministers, judges, more and more bureaucracy, hybrid ideas (free market, controlled economy, ...), corruption and inefficiencies crept in, the system degenerated into what we have today -- a hugely expensive paperworking machine that's exploited and hacked, with laws so complicated no one really understands them, with [magic](magic.md), randomness and unpredictability, producing just waste and bullshit, crumbling under own weight. This is also the way OOP went -- they started inventing static classes, multiple inheritances, interfaces, design patterns, hybrid paradigms and so on until we ended up with ugly abominations on which today's technology stands. Now a few things have to be noted. Firstly these abominations are a disaster, they came from our mistake of taking the original simple idea (simple small scale voting democracy) and saying "let's make this the only thing in the world and let's scale it a million times!" Such idea is stupid from the start and there is no doubt about that. However another evil is that people are taught to do everything this way -- today's programmers will use the mainstream OOP everywhere, even in simple programs, they don't even think about if they should, they are simply taught "always use this". This is like in real life wanting to govern a family by having elections each year to vote for the head of the family, then having members of family vote for other members of the family to be their representatives that will talk for them (the same kind of craziness as wanting to strictly respect encapsulation even in trivial programs), then if someone wants to buy anything he has to ask for a budget several months in advance and have others vote on it while an elected anti corruption committee is watching etcetc. This kind of insanity is what's normal in software nowadays. Now the only sane discussion can be had only about the usefulness and scope of the original, simple idea (simple voting in small groups, simple pure OOP) and here we say that it may be good, but only applied to just some specific situations, i.e. we say simple OOP is good for some problems but not all, just like voting is a good solution to some problems (e.g. a group of friends deciding where to go party), but not all (e.g. passengers in a car voting on which way to steer and which pedals to press).
**A [real life](irl.md) analogy** to give a bit of high level overview: the original [Smalltalk](smalltalk.md) style OOP was kind of like when society invented [democracy](democracy.md) -- a simple idea which everyone understands (we are 10 cavemen, let's just vote on stuff mkay?) that's many times useful and works well, e.g. on a scale of a village or a small city. Then cities grew bigger (just as software did), into states and empires and the idea kept getting more and more complicated -- people just wanted to keep the democracy, apply it to everything and scale it indefinitely, but for that they had to add more complexity, they implemented representatives, parliaments, senates, presidents, vicepresidents, ministers, judges, more and more bureaucracy, hybrid ideas (free market, controlled economy, ...), corruption and inefficiencies crept in, the system degenerated into what we have today -- a hugely expensive paperworking machine that's exploited and hacked, with laws so complicated no one really understands them, with [magic](magic.md), randomness and unpredictability, producing just waste and bullshit, crumbling under own weight. This is also the way OOP went -- they started inventing static classes/methods, abstract classes/methods, multiple inheritances, interfaces, design patterns, overriding, hybrid paradigms and so on until we ended up with ugly abominations on which today's technology stands. Now a few things have to be noted. Firstly these abominations are a disaster, they came from our mistake of taking the original simple idea (simple small scale voting democracy) and saying "let's make this the only thing in the world and let's scale it a million times!" Such idea is stupid from the start and there is no doubt about that. However another evil is that people are taught to do everything this way -- today's programmers will use the mainstream OOP everywhere, even in simple programs, they don't even think about if they should, they are simply taught "always use this". This is like in real life wanting to govern a family by having elections each year to vote for the head of the family, then having members of family vote for other members of the family to be their representatives that will talk for them (the same kind of craziness as wanting to strictly respect encapsulation even in trivial programs), then if someone wants to buy anything he has to ask for a budget several months in advance and have others vote on it while an elected anti corruption committee is watching etcetc. This kind of insanity is what's normal in software nowadays. Now the only sane discussion can be had only about the usefulness and scope of the original, simple idea (simple voting in small groups, simple pure OOP) and here we say that it may be good, but only applied to just some specific situations, i.e. we say simple OOP is good for some problems but not all, just like voting is a good solution to some problems (e.g. a group of friends deciding where to go party), but not all (e.g. passengers in a car voting on which way to steer and which pedals to press).
## Principles
@ -24,23 +24,25 @@ OOP furthermore comes with some basic principles such as:
## Why It's Shit
- OOP is just a bad abstraction for many problems that by their nature aren't object-oriented. OOP is not a [silver bullet](silver_bullet.md), yet it tries to behave as one. **The greatest issue of OOP is that it's trying to solve everything**. For example it forces the idea that data and [algorithms](algorithm.md) should always come together, but that's simply a stupid statement in general, there is no justification for it, some data is simply data and some algorithms are simply algorithms. You may ask what else to use instead of OOP then -- see the section below.
- OOP is just a bad [abstraction](abstraction.md) for many problems that by their nature aren't object-oriented. OOP is not a [silver bullet](silver_bullet.md), yet it tries to behave as one. **The greatest issue of OOP is that it's trying to solve everything**. For example it forces the idea that data and [algorithms](algorithm.md) should always come together, but that's simply a stupid statement in general, there is no justification for it, some data is simply data and some algorithms are simply algorithms. You may ask what else to use instead of OOP then -- see the section below.
- For simple programs (which most programs should be) such as many [Unix](unix.md) utilities OOP is simply completely unnecessary.
- OOP languages make you battle artificial restrictions rather than focus on solving the problem at hand.
- Great number of the supposed "features" and [design patterns](design_pattern.md) (setters/getters, singletons, inheritance, ...) turned out to actually be [antipatterns](antipatter.md) and burdens -- this isn't a controversial statement, even OOP proponents usually agree with this.
- OOP as any higher abstraction very often comes with overhead, memory footprint and performance loss ([bloat](bloat.md)) as well as more complex [compilers](compiler.md), language specifications, more [dependencies](dependency.md) etc.
- OOP as any higher abstraction very often comes with overhead, memory footprints and performance loss ([bloat](bloat.md)) as well as more complex [compilers](compiler.md), language specifications, more [dependencies](dependency.md), [magic](magic.md) etc.
- The relatively elegant idea of pure OOP didn't catch on and the practically used OOP languages are abomination hybrids of imperative and OOP paradigms that just take more [head space](head_space.md), create [friction](friction.md) and unnecessary issues to solve. Sane languages now allow the choice to use OOP fully, partially or avoid it completely, which leads to a two-in-one overcomplication.
- The naive idea of OOP that the real world is composed of nicely defined objects such as `Human`s and `Tree`s also showed to be completely off, we instead see shit like `AbstractIntVisitorShitFactory` etc.
- The naive idea of OOP that the [real world](irl.md) is composed of nicely defined objects such as `Human`s and `Tree`s also showed to be completely off, we instead see shit like `AbstractIntVisitorShitFactory` etc. Everyone who ever tried to make some kind of categorization knows it's usually asking for trouble, categories greatly overlap, have unclear borders, multiple parents etcetc.
- The idea that OOP would lead to code reusability also completely failed, it's simply not the case at all, implementation code of specific classes is typically burdened with internal and external dependencies just like any other bloated code. OOPer believed that their paradigm would create a world full of reusable [blackboxes](blackbox.md), but that wasn't the case, OOP is neither necessary for blackboxing, nor has the practice shown it would contribute to it -- quite on the contrary, e.g. simple imperative header-only C libraries are much more reusable than those we find in the OOP world.
- Good programmers don't need OOP because they know how to program -- OOP doesn't invent anything, it is merely a way of trying to **force** good programming mostly on incompetent programmers hired in companies, to prevent them from doing damage. However this of course doesn't work, a shit programmer will always program shit, he will find his way to fuck up despite any obstacles and if you invent obstacles good enough for stopping him from fucking up, you'll also stop him from being able to program something that works well as you tie his hands. Yes, good programmers write shit buggy code too, but that's more of a symptom of bad, overcomplicated bloated capitalist design of technology that's just asking for bugs and errors -- here OOP is trying to cure symptoms of an inherently wrong direction, it is not addressing the root cause.
- OOP just mostly repeats what other things like modules already do.
- If you want to program in object-oriented way and have a good justification for it, **you don't need an OOP language anyway**, you can emulate all aspects of OOP in simple languages like C. So instead of building the idea into the language itself and dragging it along forever and everywhere, it would be better to have optional OOP libraries.
- It generalizes and simplifies programming into a few rules of thumb such as encapsulation, again for the sake of inexperienced noobs. However there are no simple rules for how to program well, good programming requires a huge amount of experience and as in any art, good programmer knows when breaking the general rules is good. OOP doesn't let good programmers do this, it preaches things like "global variables bad" which is just too oversimplified and hurts good programming.
## The Pure OOP
## Pure OOP (The "Legit" But Unused Kind Of OOP)
TODO
Similarly to how [functional](functional.md) languages are based on some very simple mathematical system such as [lamba calculus](lambda_calculus.md), pure object oriented languages have a similar thing, most notably the **[sigma calculus](sigma_calculus.md)** (defined in the paper called *A Theory Of Primitive Objects* by *Abadi and Cardelli*).
## So Which Paradigm To Use Instead Of OOP?
After many people realized OOP is kind of shit, there has been a boom of "OOP alternatives" such as [functional](functional.md), [traits](traits.md), [agent oriented programming](agent_oriented_programming.md), all kinds of "lightweight"/optional OOP etc etc. Which one to use?