Object-Oriented Programming Is the Biggest Mistake of Computer Science
suzdalnitski.medium.com
suzdalnitski.medium.com
For instance, in most OOP languages you can define your domain model as bags of facts without methods. Then, you could define a separate domain service layer that is exclusively permitted to mutate instances of those types. Next, you enforce immutability by defining a copy ctor for every type in your model. When you return anything to a caller from a domain service you always send a copy. Same idea on create/update requests. The way I look at it, the domain services (methods) protect the model (facts) from unwanted mutations.
Having your facts separate from your methods means you can apply things like normalization and start to leverage functional and/or relational techniques. Being able to query your domain model with SQL is next-level productivity if you can manage it.
So, the biggest mistake to me in computer science is not OOP, but the blind following of any one specific doctrine to an inevitable dead-end. Good software outcomes require an incredibly difficult balance between many ideologies, as well as conformance to actual realities presented by the real world (i.e. customer requirements, regulations, developers having bad moods, etc.).
1. Lack of redundancy with the AoA sensors. This is obviously straightforward to rectify.
2. Lack of proper pilot training and awareness of the different handling characteristics of the 737 Max with MCAS compared to previous versions of the 737. Also obvious to rectify with proper training.
A design with a simple but catastrophic & easily foreseeable error isn't a good or even OK design overall. If you make a suspension bridge missing one of the towers, or lacking sufficient cable strength causing it to collapse, your bridge design is terrible, even if everything else you did was flawless.
Maybe the engineers had excuses, were rushed by management etc., but their design was still insane.
It also seems to imply that OO has cost lives, specifically with the Boeing 737 Max MCAS system and Toyota's "unintended acceleration" problem. But I can't seem to find what language MCAS was written in (I'd wager C, Fortran, Ada, and possibly some assembly based on other Boeing systems I've been involved with). And Toyota was using C.
It's probably single-handedly responsible for why Reddit, Twitter, and myriad modern popular sites are slower and buggier than ever. They are written in an un-debuggable framework...
I will however strongly recommend that one uses it with TypeScript; that way there will usually be a whole lot less to debug in the first place.
It needs structure, semantics and good abstractions, so that we can better encode programmer intention into procedures, and not only rely on algorithmic effects to tell whether a program works.
I believe the software community would be in way better shape if we approached computer science a little bit more like linguistics. We would understand each other better, we would integrate ideas easier and work more cooperatively. But until code stops being just a tool to implement some end and until code quality stops being regarded as cost we will keep writing spaghetti code. Regardless of language. Because when the team culture tolerates bad code, bad code will arise, be that in java, c, python, rust, Haskell. Whatever.
The details of how it’s implemented - inheritance vs. composition - strikes me as more of an implementation detail than a vital difference.
Game programming is a lot more fun though.
In other cases it's a meh.
No thanks.
But judging by the title, it seems click-baity. The "biggest mistake" is definitely not OOP. You can definitely abuse and misuse OOP, where other abstractions would be a better pick, but it's not just universally bad.
No mistake about it
I really enjoyed the rs-pbrt[1] project that was posted here[2] the other day, as it allowed me to compare some non-trivial code in a (to me) different and interesting language.
Does anyone have some good comparative examples for FP? Doesn't have to be as grand as rs-pbrt, but ideally something a bit realistic and non-trivial.
The member variables can be modified by the methods, which makes the variables a type of global variable, from the perspective of the method.
Then over time as your code size increases, you add more methods, and they keep modifying the member variables. Now, if you’re not careful, you can have multiple vectors modifying your member variables, any which way it wants.
Thus, when working with OOP, you can never seem to close out parts of the code that you had already completed and tested. Since the entire code base is opened for continual modifications.
And your class can be thousands of lines long. Of which you have to keep open, as you develop it. Which forces you to keep the entire code base in your head, thus increasing the cognitive load on developing the classes.
Of course, there may be ways to refactor it, but the tools given in most OOP languages, tends to be insufficient.
Functional programming doesn’t solve any of these problems by itself. There are cases where mutating state is better, and there are others, where it is worse fit. And the latter can just as well be expressed inside a class, like there is no requirement for mutation.
I think the two should go hand-in-hand, and for different parts of a program different paradigms can be used? Maybe even add actos-based programming as a possibility, but there is nothing inherently bad with OOP imo, and it is the best way to encapsulate some logic.
I think clearly this applies to functional programming as well, and probably every other way of thinking.
The issue with OOP is that it is taught, and for many programmers they think it is the only way to think so they try to make every problem a nail.
Back when C programming was more prevalent I don't think null was that big an issue because most programmers were aware of it and would check for it.
On second thought, the other big issue with null is that in many languages it just crashes the program which is a rather severe consequence you don't see for most mistakes.
Python has the concept of None, which seems to function this way. You must check if the return type is None, and react appropriately.
Didn’t Go or Rust figure this out correctly?
I think the bigger issue with null or None, though, is not necessarily using it as a return type (where that makes sense, and can be enforced by a type system) but when objects are mutated to the value of null. The bigger issue there is with mutation and side-effects, but having null there as a convenient short cut can be a foot gun that leads to lots of errors.
In a language like Python the possibility that variables may contain values of different type (such as the None value) is part of the game. An inherent tradeoff of being dynamically typed.
OOP has a lot of flaws for why it was a poor design decision, but this article doesn’t seem to address them.
Instead, it focuses on things like spaghetti code.
Besides spaghetti code it mentions that functions have non-deterministic results because the internal state of an object depends on the global state of the application as a result of being shared by reference.
OOP has more flaws which the article does not mention, true.
Peace.
Don't use Medium, please.