Thread: So, "object-oriented" programming...

  1. #1
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466

    So, "object-oriented" programming...

    ...What does it really mean?

    I'm interested in your opinions on "object oriented" programming. I've been around, and heard all the counter-arguments. I think what OOP really boils down to is this: single dispatch functions with an implicit "this" argument, and class-based polymorphism. Data hiding is ubiquitous. Class based inheritance is problematic; composition is to be preferred. Algebraic data types offer more generality than classes. "OOP" seems to be a sham.

    I've been studing OOP since Borland C++ first came out. I knew procedural code, like QBASIC and straight C. The examples from the OOP style, with the toy hierarchies, I admit... were cool, and made a lot of sense... at least for a toy examples. I've dealt with real world code that had 5 or 6 layers of inheritance, for really no reason.. except to keep me on my toes. I saw way too many mutable variables, when there was absolutely no need for it. Too many cowboy programmers creating class instance variables just to pass a result from one method to another... when there was no need at all.. the methods could just return the result to the next... and I refactored a huge mess. Not to mention, those "methods" could just as well have been declared as static functions, once the dependency on the implicit state was removed..

    It leaves me wondering if there is any real benefit to "OO" programming? I understand it thoroughly, and it is definitely beneficial when state must be shared.. but shouldn't we strive to eliminate state, as it makes our programs hard to reason about?

    EDIT:

    In my experience, refactoring the "OO" code, trying to use classes (in C# and Java) as namespaces for static methods, served to eliminate many unnecessary dependencies that were created by uncaring developers, who just threw in random instance variables that went unused between method calls. I'm of a belief that eliminating stateful variables as much as possible is the right path to good design..

    EDIT(2):

    Be nice and I'm not trolling.. Just want to get the opinions here. I've been here a long time and its hard to find a good place to talk about this stuff elsewhere!
    Last edited by MacNilly; 02-13-2017 at 07:32 AM.

  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    3,395
    Quote Originally Posted by MacNilly View Post
    It leaves me wondering if there is any real benefit to "OO" programming? I understand it thoroughly, and it is definitely beneficial when state must be shared.. but shouldn't we strive to eliminate state, as it makes our programs hard to reason about?
    If there was no benefit, it wouldn't be as common as it is. OO comes in really handy with GUI programming, for example, where you have controls with their own unique behavior, but which also behave very similarly to more basic controls. Another example might be a random number generator library. The base RNG might just be the standard C library implementation, but then you might have derived types, which access platform-specific RNG capabilities, or use other PRNG algorithms. It allows you to pass a reference (or pointer) to any base or derived RNG type, where a function expects a reference to the base RNG. There are many more examples. I encourage you to do some research on the subject yourself. If you are open to understanding, you will find a great many examples of the ways in which OO makes the code clearer and easier to reason about, even in the presence of a persistent state.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  3. #3
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Yes, I admit that GUI programming is OO based, and greatly benefits from the paradigm... but thats a particular use case that I think OO was actually based in the first place. Leaving that aside, and on to the next.. Yes, I've seen the source code to the GNU scientific library, and its C-implementation of that OO design.. a good design. Like I said, OO CAN be a good design in many instances, but I think using it as a basis of a design just because its "OO" leads to too many dependencies.. and a good design should seek to eliminate that.

    Think about it this way: Draw up a graph of the components of your system... and connect the arrows between them to designate the dependencies. Take your C header files for example... and trying to write a correct Makefile for your project. The less is better.

    EDIT: Also, saying its popular is not a valid argument for the merits of OO. I'm just saying that OO, including inheritance and mutable instance variables, is counter to decoupling and modularity.
    Last edited by MacNilly; 02-13-2017 at 07:29 AM.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    3,395
    Quote Originally Posted by MacNilly View Post
    Yes, I admit that GUI programming is OO based, and greatly benefits from the paradigm... but thats a particular use case that I think OO was actually based in the first place. Leaving that aside, and on to the next.. Yes, I've seen the source code to the GNU scientific library, and its C-implementation of that OO design.. a good design. Like I said, OO CAN be a good design in many instances, but I think using it as a basis of a design just because its "OO" leads to too many dependencies.. and a good design should seek to eliminate that.
    "Too many dependencies" is rather subjective, don't you think? Let's try to remain objective here, and look at real data, rather than opinion. If you've already made up your mind, then this thread might just be a waste of time for you.

    Quote Originally Posted by MacNilly View Post
    Think about it this way: Draw up a graph of the components of your system... and connect the arrows between them to designate the dependencies. Take your C header files for example... and trying to write a correct Makefile for your project. The less is better.
    If you're talking about OO in C, then I would agree that it's a bad idea. C is not really meant to do OO programming, although it allows some limited OO capabilities.

    Quote Originally Posted by MacNilly View Post
    EDIT: Also, saying its popular is not a valid argument for the merits of OO. I'm just saying that OO, including inheritance and mutable instance variables, is counter to decoupling and modularity.
    Things don't become popular unless they at least have a perceived benefit. OO is not the problem when it comes to dependencies. Bad design is the real problem. You can make good or bad designs in any programming paradigm. Don't just blame OO, because you don't see its general usefulness. A good design should be open to all relevant paradigms. OO, generic, procedural, and functional code may all have their place within a single application. Java and C# do not allow this to any great extent, and actually force you into an OO paradigm, even for applications that do not benefit from it. C++, on the other hand, offers all of the major paradigms in one language, and has been used to great success.

    A bad workman always blames his tools.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  5. #5
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Quote Originally Posted by Elkvis View Post
    If you're talking about OO in C, then I would agree that it's a bad idea. C is not really meant to do OO programming, although it allows some limited OO capabilities.
    No, I wasn't pointing out OO in C per se, I was just using the problem of C header file dependencies as an example.

    Quote Originally Posted by Elkvis View Post
    Bad design is the real problem. You can make good or bad designs in any programming paradigm. Don't just blame OO, because you don't see its general usefulness. A good design should be open to all relevant paradigms. OO, generic, procedural, and functional code may all have their place within a single application.
    I really love and agree with this, although I really DO see the benefits of OO (and make use of them frequently). However, I also see the downsides as opposed to a less stateful approach. And though I love C, you're right, I really don't like C++, but I did not come here to say anything about C++.

    EDIT: Hmm, rather than me "blaming" OO, rather see it as an open invitation to people here to show me a real benefit of OO.
    Last edited by MacNilly; 02-13-2017 at 07:59 AM.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,231
    EDIT: Hmm, rather than me "blaming" OO, rather see it as an open invitation to people here to show me a real benefit of OO.
    I have to admit I'm a bit confused where to take the thread. You seem to understand that OO helps manage programs with state by controlling how and where it is accessed and changed and represented. Is that not a good enough benefit or something?

    If we agree that stateless operations are better in programs, do you agree that there are some operations that must have state, like I/O? Then OO might be the best way to program it that we know of. Where to go from here?

  7. #7
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Quote Originally Posted by whiteflags View Post
    I have to admit I'm a bit confused where to take the thread. You seem to understand that OO helps manage programs with state by controlling how and where it is accessed and changed and represented. Is that not a good enough benefit or something?
    It is a confusing topic.. however, I disagree with the sentiment that OO can control how "it" (presuming data) is changed and represented.. In fact, that is the problem with it. In the face of mutable state, how can we control it? I guess my question is of the philosophical bent.

    Quote Originally Posted by whiteflags View Post
    If we agree that stateless operations are better in programs, do you agree that there are some operations that must have state, like I/O? Then OO might be the best way to program it that we know of. Where to go from here?
    Of course, I agree. However, I think in many instances OO design may be superfluous, where a straightforward procedural (or data-driven) design might be a better fit: static functions operating on immutable data structures. From a practical standpoint, when you or I are groking a piece of code (in a method of a class), the less state we need consider (in the form of mutable instance variables, or mutable arguments), the easier our job, yes? At some point, the majority of these methods can become independent functions that do not need to be class methods or rely on some shared mutable state. My claim is that in my experience, the actual required state is much less than is implemented in practice. [OO tends to lead to unnecessary dependencies]

    In additon, the example of I/O may not be the best... I/O is not inherently OO.

    EDIT: Maybe I should change the title of the thread to "Not everything is a class"?

    Food for thought: How many of you have tried to fit some design into a class hierarchy? Maybe a Collections library? Feels like pulling teeth? Well, it won't fit into a hierarchy. Why try to force it? Even if we go out of our way to make it fit, it reeks. Therefore, why the OO design?
    Last edited by MacNilly; 02-13-2017 at 08:45 AM.

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,231
    however, I disagree with the sentiment that OO can control how "it" (presuming data) is changed and represented.. In fact, that is the problem with it. In the face of mutable state, how can we control it?
    I guess that's where we should start. I mean, presuming you choose to use an object in your program -- there are a few choice ways to initialize the object to begin with. Then when you program with the object you are basically calling methods to do different things. The only way to really change anything about the object is to call methods, which are algorithms that you've programmed and tested and can basically prove that the objects work. Hence it should not be hard to see how using objects in a stateful part of the program is helpful.

    My claim is that in my experience, the actual required state is much less than is implemented in practice.
    At the very least that's an interesting experience. It's hard not to see things in a stateful way if all you know are procedural and OO paradigms, so maybe that's why they're overused.
    In additon, the example of I/O may not be the best... I/O is not inherently OO.
    I don't recall saying that it was inherently OO, what I was driving at was different, but you answered my question anyway.

  9. #9
    Registered User
    Join Date
    Oct 2006
    Posts
    3,395
    Quote Originally Posted by MacNilly View Post
    It is a confusing topic.. however, I disagree with the sentiment that OO can control how "it" (presuming data) is changed and represented.. In fact, that is the problem with it. In the face of mutable state, how can we control it? I guess my question is of the philosophical bent.
    Languages designed with OO in mind tend to have a concept of private object state data - data that can only be modified by the object itself, or in most languages, any object of the same type. A good design hides the private data behind a public interface, so that other code can only access the things that are public. C does not natively have this capability, except through concepts like the PIMPL idiom.


    Quote Originally Posted by MacNilly View Post
    I think in many instances OO design may be superfluous, where a straightforward procedural (or data-driven) design might be a better fit
    And a great deal of procedural code has been written, which might benefit from an OO approach. The knife cuts both ways.

    Quote Originally Posted by MacNilly View Post
    static functions operating on immutable data structures. From a practical standpoint, when you or I are groking a piece of code (in a method of a class), the less state we need consider (in the form of mutable instance variables, or mutable arguments), the easier our job, yes? At some point, the majority of these methods can become independent functions that do not need to be class methods or rely on some shared mutable state. My claim is that in my experience, the actual required state is much less than is implemented in practice.
    OO shines brightest in cases where state is necessary.

    Quote Originally Posted by MacNilly View Post
    OO tends to lead to unnecessary dependencies
    That's like saying that building a house tends to lead to unnecessary trips to the lumber yard. A lousy programmer will design bad systems that have unnecessary dependencies, regardless of paradigm. A good programmer will create a design that has only the dependencies it needs. Again, don't blame the tools.

    Quote Originally Posted by MacNilly View Post
    In additon, the example of I/O may not be the best... I/O is not inherently OO.
    Upon what evidence do you base this statement? Who is to say that a particular operation is or is not inherently OO? Let's take an I/O port, for example. It has properties, and it has operations that can be performed on it. Explain how that does not lend itself to OO concepts.

    Quote Originally Posted by MacNilly View Post
    EDIT: Maybe I should change the title of the thread to "Not everything is a class"?
    Nobody ever said everything should be a class. It's just a logical way to organize things that represent real-world concepts.

    Quote Originally Posted by MacNilly View Post
    Food for thought: How many of you have tried to fit some design into a class hierarchy? Maybe a Collections library? Feels like pulling teeth? Well, it won't fit into a hierarchy. Why try to force it? Even if we go out of our way to make it fit, it reeks. Therefore, why the OO design?
    Why not the OO design? Why not have an abstract base class called LinkedList, and have SinglyLinkedList and DoublyLinkedList derived from it? They share a great deal in common, so it makes sense to me. I agree that an entire collections library wouldn't work well as a single hierarchy, but certain segments of it sure would.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  10. #10
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Angola
    Posts
    8,438
    Quote Originally Posted by Elkvis View Post
    Things don't become popular unless they at least have a perceived benefit.
    Note necessarily true for all things. And as such could be false for OOP.

    Quote Originally Posted by Elkvis View Post
    Bad design is the real problem. You can make good or bad designs in any programming paradigm. Don't just blame OO, because you don't see its general usefulness.
    Oh, but I will blame OOP! The problem is that OOP doesn't scale well. Any inherent complexity to the project gets absorbed like a sponge by OOP. Instead of resolveing it, OOP will show you the complexity of your project like no other paradigm. The greatest lie about OOP is the idea that the simplicity of its core principles caries over as your projects become bigger and more complex. But it doesn't. OOP exposes all that complexity and spreads it out over all manner of distinct tools in OOP, like no other software paradigm in existence. It's a nightmare to maintain. And you can tell to my face as many times as you want that if the application is well designed that won't happen, and the only answer I will give you is then you do the design of a complex project in the real world of competitive business computer programming to see if that sticks. Because you can't do good design in OOP for large projects. The paradigm will force you to explode your design in all sort of tiny pieces that are a nightmare to maintain or refactor.

    It's painful to watch the suffering of someone needing to work out inheritance, composition, virtual classes, top level classes, sealed classes, interface classes without any state whatsoever, static methods, rules for construction and destruction of objects, and a legion of so many other things, all working on top of a programming language already existing syntax and semantics. And once the programming is done, and all the bugs that OOP excels at drawing in to your project are in, it is even more painful watching someone trying to make sense of it as they have to maintain the code. Naturally it all gets done, because programmers are suckers for punishment and naive enough to see beauty in complex code constructions and interactions. Only newbs think programming is simple. Right? But the truth of the matter is that OOP answer very few problems but keeps getting announced as a solution to programming.

    Quote Originally Posted by Elkvis View Post
    A good design should be open to all relevant paradigms. OO, generic, procedural, and functional code may all have their place within a single application. Java and C# do not allow this to any great extent, and actually force you into an OO paradigm, even for applications that do not benefit from it. C++, on the other hand, offers all of the major paradigms in one language, and has been used to great success.
    And here indeed is where OOP excels. When it is not meant as the core of your code design, but merely as a tool to add to your procedural codebase.
    Unfortunately, the market presses business software development the other way. The promises of fast code development and attractive visual interfaces of languages like C# or Java are a real thing that are hard to ignore. And so people get drawn into exclusive OOP in droves and fed with all the OOP propaganda bs, perhaps in an attempt to make them feel worse about themselves instead of the actual paradigm. As if to say, if you find this confusing, unnecessarily complex or hard to maintain, then you are doing it wrong. As if there was ever a right way to do OOP... *rolls eyes*
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  11. #11
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,653
    To Mario's last paragraph's point, paradigm zeal is a real thing for all paradigms. I've yet to really find someone who's been like, "I use the appropriate paradigms when they match the problem I'm trying to solve."

    OOP zealotry is equivalent to FP zealotry and then people wouldn't even consider something imperative.

  12. #12
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Quote Originally Posted by MutantJohn View Post
    OOP zealotry is equivalent to FP zealotry and then people wouldn't even consider something imperative.
    I agree, and thus tend to admire languages that allow a multi-paradigm approach (like C++ and Python).

    Like a lot of people, I learned procedural programming (QBASIC, C) first, then OO (C++, Java). It was a fairly easy transition from C to C++ to Java to Python. The OO concept of inheritance and virtual method dispatch is difficult for many people to comprehend (it was for me), but its one of those "aha!" moments. Getting older, I later studied functional programming (Scheme, and Standard ML). That was another "aha!" moment, and I realized the elimination of state (as much as possible) is a Good Thing (TM). And then I started questioning the "true" benefits of all the OO knowledge I had poured sweat over... and was left feeling that OO (inheritence and class based polymorphism) might not be so great, after all. I'm a of the belief that OO is a poor substitute for more powerful concepts in other languages:

    - Classes as types are a poor substitute for general, recursive, algebraic types (ADTS).
    - The single dispatch model is limited, and forces arbitrary design decisions such as "what class should this method go?"
    - Inheritance is a fragile construct (except in the simplest of cases), and requires constant refactoring.
    - Clausal function definitions, in addition to generalized ADTs, with pattern matching form a superset of anything that can be done in OO. Why not use a better tool?

    However, I'm no zealot of any paradigm, and I think "pure" languages like Haskell throw the imperative baby out with the bathwater.

    If they made C++ with generalized algebraic data types, pattern matching functions, garbage collection, and get rid of classes, I might be a convert!

  13. #13
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Quote Originally Posted by whiteflags View Post
    The only way to really change anything about the object is to call methods, which are algorithms that you've programmed and tested and can basically prove that the objects work.
    There is also the problem, due to the shared state between methods, of putting the object into an invalid state by calling the wrong sequence of methods. With inheritance, it is very possible to break the implementation -- especially without knowing how the base class was implemented.

  14. #14
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,653
    Well, keep in mind, every C++ container is a functor.

    C++ readily supports many of the FP constructs that Haskell has. However, Haskell's constructs aren't always machine efficient. A trade-off is that C++ is fast and Haskell's strings are linked lists of chars.

  15. #15
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Quote Originally Posted by MutantJohn View Post
    However, Haskell's constructs aren't always machine efficient.
    I realize that. That's why I want C++ with the aforementioned features. I don't see why it can't be compiled to machine code. But you've gotta be a genius to implement that compiler. Yeah, Haskell is slow.. Python is also slow, and its totally OO.

    I realized that Haskell (or any "pure" functional programming) was over-rated when I saw the standard "merge-sort defined in 5 lines" style of code.. and barfed over the O(N^2) complexity. I'm sorry, but merge sort (or any good sort) must be O(log N), and anything less is reverting to a bubble or selection sort. I don't care that the result is the same... I care about efficiency, as any good computer guy should. It's simply not possible to implement an efficient sort using a linked list as the underlying data structure. You need arrays with mutable cells for that.
    Last edited by MacNilly; 02-13-2017 at 04:51 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 12-08-2014, 08:12 PM
  2. Replies: 9
    Last Post: 09-19-2011, 03:12 AM
  3. "itoa"-"_itoa" , "inp"-"_inp", Why some functions have "
    By L.O.K. in forum Windows Programming
    Replies: 5
    Last Post: 12-08-2002, 08:25 AM
  4. "CWnd"-"HWnd","CBitmap"-"HBitmap"...., What is mean by "
    By L.O.K. in forum Windows Programming
    Replies: 2
    Last Post: 12-04-2002, 07:59 AM
  5. "Object reference not set to an instance of an object"
    By Manitoadlet in forum C++ Programming
    Replies: 6
    Last Post: 09-10-2002, 06:09 PM

Tags for this Thread