OOP “is really just a common sense extension of structured programming”
archive.org
archive.org
It's probably best to start off a solution with plain old data structures, and plain old functions (ie. procedural style). Build with that until right abstractions or separations emerge.
This can only become a problem if you pay little to no attention to modularization, software architecture, and even encapsulation.
The responsibility of a paradigm and a language is to allow a developer to freely express their concepts. The programming paradigm is not to blame if the developer chooses to express poorly thought-out ideas that are riddled with detrimental consequences.
You're giving the textbook example of problems created and solved by putting together a working software architecture. Books like Bob Martin's "Clean Architecture" refer explicitly to needs to accommodate changes to business and application layers, and the need to design components to accommodate changes, and the book is language-agnostic.
My point is it’s easier to modularize and encapsulate properly with procedural or functional paradigms because they don’t force you to do that work before you start solving problems. The dev flow is: solve problem, then modularize. With OOP, the flow is: modularize, then solve problem.
I’m simplifying and of course you can architect correctly upfront, it’s just harder because you’re doing speculative generalization (akin to premature optimization).
That's a poorly put-together red-herring. Brainfuck is not one of the leading production programming languages that has been used for decades to write all sorts of applications, from operating systems to web services and specially desktop applications, AAA games, and high-performance computing. Brainfuck is a gimmick "esoteric" programming language used as a challenge.
> My point is it’s easier to modularize and encapsulate properly with procedural or functional paradigms because they don’t force you to do that work before you start solving problems.
The thing is your point does not hold at all. It's trivial to modularize and encapsulate and even isolate components with C++. You only need to want to do it. If you don't want to modularize or encapsulate or isolate components then you get what you want. Don't blame the language for the software architecture you chose to adopt for your project.
First you backtrack your generalization regarding languages, which makes one ask what other omitted features have to be present to rely on the statement.
Second you're not supporting your claim "It's trivial to modularize and encapsulate and even isolate components with C++. You only need to want to do it." It directly contradicts the observation that programs, when written, are often found to be designed incorrectly, and it's important that the language would support enough their recomposition. Just wanting to make a good architecture doesn't make it right all by itself, sometimes you have to change already existing things, and how easy it is has a lot to do with the language.
I think that "freely" is what GP is complaining about; that OOP practices limit your freedom by encouraging early lock-in and making past decisions hard to revisit in light of new facts.
I'm not sure I entirely agree, mind you, but I do think you're in more agreement than disagreement.
I've tried everything but my favored approach these days is just to stream of conscious psuedocode in main() to get the shape of what needs to happen, and then backfill until there's something working. Once I know what I want, only then do I break things up so that everything is in the right place. It seems to end well every time.
tl;dr: bottom-up, and top-down are too extreme!
You could apply TDD at this point. Doesn't have to be before you write a single line of code.
But eventually a junior developer realizes that a Triangle is an PolygonalOpenFrameMetallicPercussionInstrument and it now has 4kb of private state, 307 inherited member functions, and floods your console when its logged.
I love OOP, but caution is indeed warranted.
In fact "composition over inheritance" is a thing in the OOP world.
You don't know how much memory an object of a given type takes to instantiate. This makes object allocation slower. This also means that you can't allocate a Vector<T> inline. It has to be a vector of pointers.
You don't know what fields a type has. This makes GC scanning more expensive.
You can't optimize the layout of a type. If you know an object doesn't have subtypes, you can move it's fields around to reduce padding. If you want to be able to look up fields quickly, you need to put all the fields of the supertype first in memory which will increase the size of your objects.
On OOP languages with GC, you can reduce GC scanning by having precise GC, and if the languages support value types by making use of structs with method pointers.
With the help of PGO for AOT or the JIT, the compiler can optimize the layout of types for the target architecture.
Inheritance x composition is orthogonal to OO.
Even though I once took a highschool C++ course long ago that talked about OOP and made us do a few things with it.....
I still have no idea what OOP really is, and why I need it. Unless I'm using it without knowing, I have a feeling I'm either dumber than I think or people have lost their minds. I can't tell.
The downside of being self-taught is well-known - you might end up convincing yourself that for loops don't work, strings with more than 10 characters are unreliable, numbers can only reliably be added using BigDecimal, etc.
The general answer seems to be that OOP starts really helping when many people/teams are involved.
Being self taught and a one person team I suppose hasn't forced me into it yet.
The basic low down is that this is all about encapsulation (tidying things away in boxes).
You hopefully already know a bit about that.
Say you just have all globals through all your files, you probably know you end up with a big mess of spaghetti.
To help with that, you've probably already learned about tidying away code and variables into functions. And you might know that if you have a local variable, it is only visible inside the scope of your function. If you're doing it right, then nothing outside your function will ever directly touch the local variables inside the function, or vice versa.
This makes it really really easy to reason about what happens inside the function, since -with the exception of your parameters and your return- what happens in vegas... uhh... your function, stays in your function. And the inputs and outputs to the function are well defined.
This saves hours and hours of hunting out every last spot that some global was used, just in case it is interfering with something 1000 lines away. If you've done a lot of programming, you've probably been there a hundred times, cursing the laziness of Past You as you went.
Maybe you also separate your program out into different files. Model.php, View.php, Controller.php DoImportantThing.php ... maybe something like that?
So you probably already realize that tidying things away in boxes is a good idea. Everything you can tidy or organize away inside some box is something you don't need to worry about elsewhere at least. Out of sight is out of mind.
Wouldn't it be great if there were more ways to help you tidy things away into boxes? Well, we're in luck. PHP has classes and objects. These are a further way to organize functions and data together into a next-size box.
The idea is to tightly control what gets in and what gets out of these boxes again. And if you do, that's an additional level of things you don't need to worry about constantly. This frees up that part of your mind for other things.
Of course if you're a PHP programmer you don't NEED to use classes and objects. You don't NEED to use anything. But they're a very powerful tool to help you keep your code squared away. And since they're built right in to the language already, right at hand, why wouldn't you use them?
Classes and objects make most non-trivial projects easier and quicker to write (especially if you can reuse old classes, which you often can!) , and they make medium to large projects rather more manageable and tractable.
If you poke me, I could find some time to show you how you can make classes and objects work for you?
[disclaimer: Classes and Objects are definitely not the first/last/only/best/worst tools to organize code. Different languages have different tools sometimes. PHP just happens to provide Classes and Objects, so that's what you've got to work with there.]
Yes. A lot of what people profess about the "clean" ways to write OOP is essentially just the same as using Functions with Namespaces
One neat use of classes is model objects in scikit-learn. But R manages to do the same thing with a much more basic system called S3. In this system, you have "generic" functions which dispatch to different methods based on the data type of the first argument. This is used to endow the programming environment with predict and plot functions that behave differently depending on what kind of model you feed into them. This is essentially the same as how two different OOP classes can have two different methods with the same name. But S3 has none of the other trappings of object-oriented programming whatsoever: no encapsulation, no inheritance, no polymorphism.
I found it a fascinating revelation. It's hard to point to anything that R's object system makes unnecessarily difficult, any killer app that proves how pure OOP is better. I would guess that traditional OOP excels in GUI systems, but outside that context, people seem to increasingly find it wanting as a paradigm. We are seeing an evolution away from unipolar OOP ideology and towards a more multipolar exploration of different paradigms and their comparative advantages.
http://harmful.cat-v.org/software/OO_programming/
"Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function." – John Carmack
Unfortunately, many college-educated programmers have been taught OOP design ideology and profess it uncritically.
But I can agree with the Carmack quote, but that in itself doesn’t contradict OOP’s supposed benefits.
Say you want to draw a window, it's one of many windows in your program. You could either write out the code to draw a window each and every time you want to draw a window, but that's probably inefficient at best and a nightmare to maintain at worst.
So you instead write a generalized class to draw a window. You then invoke that class as a new object when you want to draw a window, and pass to it any information unique to this particular window (eg: dimensions, contents).
This means the code to draw a window only exists once in your program. If you need to change how windows are drawn, you only need to change the one class instead of thousands of instances of drawing windows.
In essence, any action that you are likely to repeat many times in a program benefits from object oriented programming because it centralizes the code in one place and is abstracted away when the time comes to use it.
By contrast, if a given action is something a program would only do once or at most very seldomly, object oriented programming starts to lose importance because there's little value in centralizing and abstracting away a piece of code that will only ever execute once anyway.
This isn't really the unique benefit of OOP. Plain functions also centralize code in one place and allow you to avoid writing repetitive code.
Using Classes when you should be using functions is one of my biggest peeves with OOP and the programmers who write it.
Especially those who wind up writing a "Window" Class with one function "draw" and nothing else
Doesn't mean that you're dumb or that other people lost their minds. My guess is you haven't given it a serious go, which is fine if you don't have a need for it. I personally find OOP fantastic for large codebases with multiple people working on them. Makes code a lot more maintainable and easier to reason about. The downside is that folks without a strong sense of architecture can get carried away with enterprise patterns and end up with abstractions on top of unnecessary abstractions. The basic tenets of OOP should be easy to understand if you just spend some time on it, though benefits can be hard to see if you haven't experienced procedural spaghetti code.
Then I read some articles. And I read forum posts. And I read comments. And I read OOP doesn't need this or that. I read multiple people define OOP in many different ways. Now I don't know how to define OOP.
I thought I could "know OOP if I saw it". And then I wrote code. I wrote in procedural languages. I wrote in functional languages. I wrote in declarative languages. I wrote in languages that like to blur the lines between them. And now I don't really know where the lines are. It all is just "programming".
Answering the question: "What is Object-Oriented Programming" used to be so easy. Now I don't know.
The whole abstract factory generator class iterator thing I see in other languages scares the bejeezus out of me.
My issue with `this` and things like it is that the first argument (the 'object') is usually the most important thing, and it's easier to read methods if they have a name.
Ok, you can call this deixis but do you need to? Clearly not.
I think it's fair to skip over a comment using terminology you find tiresome, be it because you aren't familiar, or you find it irritating for some reason, or for any reason; it's your time. I think it's unnecessary to insist we all use the same terminology, as that just limits what conversations can be had and who can have them. One of the things that makes HN feel magical is when people from a weird discipline jump in to give their two cents, and they add value to the community when they bring their terminology with them.
This does not mean that we need to dumb things down, but if OP can not explain things in a simplified matter, I'd take it as a signal that OP's criticism at best as non-practical and at worst as pseudo-intellectual BS.
Dismissing someone for using different terminology is dismissing someone who could surprise you or teach you something new because you don't like the aesthetics of their speech and you aren't willing to put in the effort to understand them. If you don't want to spend your time that way I understand, but why is that a stance? Why isn't that just how you've prioritized your day, without making it a moral judgement about the quality of their speech?
> This does not mean that we need to dumb things down, but if OP can not explain things in a simplified matter, I'd take it as a signal that OP's criticism at best as non-practical and at worst as pseudo-intellectual BS.
What you're saying here is that you'd rather rely on this heuristic to dismiss what they have to say, then figure out whether what they say has value. And you do you. But this isn't a reflection on anyone other than you. It isn't a criticism of their statement. You're kinda cheating yourself. You've just decided that along this certain axis, your thinking is done expanding and you have no more to learn. And that's unfortunate, I hope you'll reconsider because there's a lot of richness there.
I didn't say that the type of speech alone is enough to dismiss the argument. I am saying that resorting to terms more complicated than needed hinders communication.
If "words are tools for thought", OP is using the wrong tool and you are jerking off to someone who is employing a (overtly fancy) chisel to sand a block of wood.
(And yes, I did read up on the terms. His criticism is still vague and does not seem rooted in actual experience as a programmer, teacher or programming language designer.)
This being precisely why I found it to be a fresh and interesting viewpoint; I've heard a lot from programmers and language designers on this topic, I hadn't heard from linguists before. I found their use of different tools of thought than I had seen applied to this area intriguing and it made me see things in a different way; you seem to have interpreted this as "using the wrong tools" because they weren't the ones you were used to. This is exactly what I was saying; you're limiting the conversation to an insular set of perspectives.
You've bought my premise about what you're saying, and in lieu of justification you've provided some cheap insults. I'm glad we understand each other.
> I hadn't heard from linguists before.
Are you sure? Larry Wall, creator of Perl, is a linguist. His education certainly guided his decisions when designing the language. He certainly had different "tools of thought" compared to other programmers at the time, and it shows. You can hear him multiple talks and read books from him about the topic, and none of them are filled with out-of-context, unnecessary jargon.
Terms?
"I think you meant 'words' which I also find annoying, but don't feel the need to dress that up in fancy words."
I don't feel the need to blunt precise terms down to imprecise terms.
If I did find "fancy terms" annoying, I wouldn't be proud of nor advertise that.
It's nonsense though because this/self is barely more than syntactic sugar for what C programmers do anyway - in fact languages with UFCS let you choose arbitrarily. Writing free functions with `this` as the first parameter doesn't really change anything.
0. https://www.tech.dmu.ac.uk/~mjdean/notes/modules/education/E...
Concurrency, syntactic sugar, object oriented, monotonic clock, these all sound like babble to someone uninitiated as well.
Of course this was inevitable given the place orientated von Neumann architecture (the tape, with its distinct locations). Much as OO practitioners like to think OO is special or deep in some sense, it is in fact just a conceptual hack to accommodate the inherent clumsiness of our particular adding machines, dressing their flaws in fancy clothes to hide our shame. If it wasn't for C pointers, programmers would think OO was some sort of nightmare fuel from another dimension.
Isolating some kinds of state in more manageable units can be very handy while remaining maintainable.
Even inheritance can be nice under the right circumstance.
Object oriented programming? An unmitigated disaster.
As for the handwaving about simulation & modelling and We Must Design The Matrix and all that nonsense... not applicable to most programming.
OOP helps encapsulate state to make it more manageable.
I am starting to reject OOP because I find working at reducing state is much more fruitful than encapsulating it.
NB: I am from California and I like object oriented programming.
Programming to an interface, composition, immutable classes and objects as fancy closures that can do more than one thing: Drake-yes-please.jpg
Inheritance for code sharing: Drake-no-thanks.jpg.
One thing I really miss from my Java days, and which I don’t really think has anything to do with OOP, is the concept of package visibility. Private data for the class itself. Protected data for inheritors if you dare have them. Public for anyone using your library. And package level visibility for me and my team to have special privileged access to these things in the same module, but which one outside of it is allowed to touch. It’s a great feature for large groups of programmers.
C++ has that in the form of internal linkage. You can have all the symbols you want that are only visible within your own translation unit.
Without OOP, we quickly get into codebases much like JavaScript where every new framework attempts to reinvent the same thing in even more contrived ways.
The only place where OOP style doesn't make sense is in stateless programs, which a lot of web backends are (but even there, it's often useful to hold connections and to create good interfaces).
Don't let your code in any language go down the JavaScript framework path.
Traits and type classes are a much better solution that offer far more flexibility, yet still allow the programmer their own balance of expressiveness and rigidity.
Of course data can have defined behavior. Don't try to marshall it into genetic lineages of parents and ancestors. That's an orthogonal and entirely made up problem.
Just pick a modular language like Modula-2, and add the capability to store module instances into variables, and extend them from there.
Polymorphism and dynamic dispatch at their root are plain function pointers, and anything else is just syntax sugar to avoid manually dealing with them.
Languages like Oberon or Lisp show how minimal the language has to have native support for OOP features, while still supporting most of its concepts.
The Actor model seems to fit well with OOP also.
0. http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-...
Simula was the first language to have objects but Alan Kay's Smalltalk was what really caused it to take off and is what most OOP languages today were derived from. Today he feels he mis-named it and that he should have called it Message-Based Programming, which is what he feels should be the primary focus of languages with objects.
Most OOP languages today are not message-based and do not offer the full benefits of message-based programming. A few that do are Self, Ruby, and Erlang.
The reason OOP seems like a buzzword with no clear meaning is because there are so many languages that implement OOP only partially and not always the same parts.