5 ms·
> OOP encourages developers to over-think object hierarchies and build baroque code that is prematurely generalized. How does it encourage exactly? In my exper
by mieseratte 7y ago
> OOP encourages developers to over-think object hierarchies and build baroque code that is prematurely generalized.
How does it encourage exactly? In my experience sophomoric programmers are just as capable of over-engineering in a functional environment. Seems more a function of cargo-cult behavior than anything else.
- hombre_fatal 7y agoIn my experience, the first thing people do in an OOP language is name their first classes. Like maybe you have a Twitter crawler so you create a Crawler class and stick state into it. And maybe you create a few more arbitrary classes that collaborate arbitrarily, and it's like name-driven development. State sprinkled around. And these nouns basically solidify as abstractions that last for the life of the project. FP on the other hand inverted this experience for me. I thought of the data first and merely built a pipeline on that data. Didn't have to invent nouns and classes. Just transformations on that data. OOP has most people inventing abstractions on day 1 like classes by its very nature. It never felt like the right way to approach a problem to me. And of course, on HN there's an endless amount of "well, OOP is just misunderstood, you don't have to do it like that" which just never syncs up with my real life experience.
- vnorilo 7y agoYes. Humans tend to everyday-think in terms of agents with identity. Take that mentality over to programming and you will end up with coupling and state, typical OOP spaghetti. Of course, good OOProgrammers don't do this. I remember reading C++ intro books in my early teens. Class Train prints choo choo. Class Car says honk honk. Both inherit Vehicle. I thought, why do they do this dumb shit and how is it related to programming?
- merlincorey 7y ago> I remember reading C++ intro books in my early teens. Class Train prints choo choo. Class Car says honk honk. Both inherit Vehicle. I thought, why do they do this dumb shit and how is it related to programming? As someone who was once a known C++ and OOP zealot that later found their way to functional programming and now sits middle of the road on things, I am curious how exactly you would go about implementing polymorphism in C++ for, say a video game, where different entities had different sounds such that a single function can play the sounds of many entities without using this "train is a vehicle" and "car is a vehicle" text-book inheritance? I'm not saying I cannot think of other ways to do it, but I am not really sure what the deficiency in your example actually is -- that seems like a pretty straightforward use of inheritance, and I can see it being useful in say a game as I made an example of.
- vnorilo 7y agoSure; inheritance is a relatively efficient way to implement single dispatch polymorphism in C++. Not much more to it. Thinking about it in that way has made my life easier. Not that there's anything wrong as such in the example, it is just somehow all the examples were so inane.
- Jtsummers 7y agoIn that case, does it need to be a property of the class to play the "Toot toot" wav file instead of the "Honk honk" wav file? Or is that a property of the object. Distinct classes make sense when they have distinct behaviors, in this case they have the same behavior (play a sound) but with a different effect (tooting or honking). Make it a parameter to the class constructor. Would you make distinct classes based on the amount of damage creatures could inflict on the PC? Or would you make a parameterized class that allows the amount of damage to be changed?
- merlincorey 7y agoI was thinking definitely of more complicated sounds than simply playing a static wave form stored in a file. I absolutely agree if that was the case, it's very simple to parameterize it. In a more complicated situation, where perhaps you want some sounds to be simple wave forms and some sounds to be more complex sequences of wave forms mixed in some manner, then I was envisioning a `SoundEffect` base class from which simple and complex sounds could be derived, providing a single-dispatch polymorphism. A `SoundEffect` instance (or more likely mapping of names to sound effects) would certainly be a property of whatever entity contained it... but the `CarHornSoundEffect` is a `SoundEffect` and `TrainHornSoundEffect` is a `SoundEffect` relationship remains a straightforward and effective use of inheritance to provide single-dispatch polymorphism.
- mieseratte 7y ago> In my experience, the first thing people do in an OOP language is name their first classes. Like maybe you have a Twitter crawler so you create a Crawler class and stick state into it. And maybe you create a few more arbitrary classes that collaborate arbitrarily, and it's like name-driven development. State sprinkled around. And these nouns basically solidify as abstractions that last for the life of the project. FP was and really still is a more of a "nerdy" thing in the wider world, so perhaps your seeing good FP vs bad OOP is more a function of the people involved. Think of the kind of persons who learn one language (Java / C#) at university with a "Cs get degrees" mentality about their skillset. > I thought of the data first and merely built a pipeline on that data. One can do this in any paradigm. One must also realize that this isn't a common (enough) refrain and that there is also a large difference between knowing it and knowing it. With that said, I ask again: What about OOP specifically encourages terrible design?
- dentemple 7y agoHow does one "over-engineer" a functional environment? By breaking functions down into even smaller pieces? By minimizing side-effects even further than before? These are all good things to do no matter what. My one and only issue that I have with the "design"-side of FP is that it can be tough to organize multiple functions in an intuitive way. (The "soup of functions" effect, essentially). It makes coming on to a new codebase tedious to trace, but I'd still rather than dealing with spaghetti OOP.
- imtringued 7y agoYou can over-engineer point free style to create an uncomprehensible code base. Point free style with more than 1 unapplied parameter is basically a nightmare. https://wiki.haskell.org/Pointfree#Tool_support https://wiki.haskell.org/Pointfree#Tool_support
- mieseratte 7y ago> How does one "over-engineer" a functional environment? By breaking functions down into even smaller pieces? By minimizing side-effects even further than before? These are all good things to do no matter what. Off hand, overly tight coupling of unrelated by superficially comparable functions. Of course one can also do this in OOP environments as well. This is related to "God Functions" that are meant to handle way too much. There's also those who fundamentally fail to understand what the point of FP is. The belief that it's just "my function isn't in a class."
- setr 7y agoPerhaps by generalizing to the point of futility
- ncmncm 7y agoAnything can be over-engineered, simply by violating Occam's Razor. Bad programs are filled with stuff operating on other stuff that is not essential. Programs in Lisp and Haskell do this as much as in any language, because few love simplicity.