Couldn't agree more
Couldn't agree more
Java is the extreme case of this. Patterns like abstract visitor factories are hacks to express situations that cannot be expressed in an obvious way.
Inheritance is just one of multiple facets of safe code reuse in OOP. Aggregation, composition, encapsulation are as are much as fundamental notions in OOP as inheritance. So i think reducing OOP in general, and java in particular to "inheritance based OOP" is a miss characterization
> are that it fits very few problems well, that it usually causes lots of problems and that many programming languages only have inheritance based OOP in their toolbox.
Do you have any objective way to measure that ?
> Patterns like abstract visitor factories are hacks to express situations that cannot be expressed in an obvious way.
But isnt that the reason to have a pattern ? An easy way to expression a non obvious recurring situation ?
You say that as if these things are not just as easily expressed in FP -- if not even easier.
Aggregation is just records-of-records.
Encapsulation is just "abstract data types", e.g. ML modules with abstract members, or non-exported data constructors in Haskell. Another option would be simply closing over whatever you're trying to hide. Another option would be existential types. (There's some overlap among all of these.)
Composition... well, actually I'm not sure what exactly you mean by "composition" in the context of OO. Can you explain what you mean?
No, that's what you read. What i said what was i wrote... OOP is bigger than inheritance.
> -- if not even easier.
Again, this kind of statement really sound like empty FP propaganda to me.
> Encapsulation is just "abstract data types", e.g. ML modules with abstract members, or non-exported data constructors in Haskell. Another option would be simply closing over whatever you're trying to hide. Another option would be existential types. (There's some overlap among all of these.)
Or "abstract data types" is just Encapsulation...
I think you may have misunderstood my intent. I was just trying to say "FP can do these things too".
> Again, this kind of statement really sound like empty FP propaganda to me.
Right, so any type of even very modest support for X is "empty X propaganda". Can we please assume at least a modicum of good faith here?
> Or "abstract data types" is just Encapsulation...
Oh, so "semantics" it is then. Oh, well.
FWIW, I think I'm right in saying that ADTs were invented quite a bit before OOP & "Encapsulation".
I notice that you also didn't answer my question of what Composition actually means in OOP. Do you have an answer? I promise, I wasn't being facetious.
So true! Sadly, most programmers' idea of an “abstract data type” is a class. :-p
EDIT: I was being a bit facetious, but we were discussing programming languages, so maybe not that much of a stretch...?
There's a reason why composition is preferred over inheritance. There's also good reason why some programmers will take it to the extreme and say that it ALWAYS causes more problems. Some languages lack of providing an appropriate aggregation alternative generally keeps inheritance alive.
Some people will hold onto their positive notions about inheritance too, and that's fine, but there's a reason why many people advocate strongly against it (and why some modern language designers skip it altogether!)
I might not be understanding well, but are you talking of languages that happen to have no _composition_? But do have inheritance? Sounds like those with inheritance are a strict subset of those with composition (which in turn would be all but fringe languages).
Inheritance is everything else but safe: you have to check if you broke the behavior of all methods and public fields you are inheriting. How often do you go through all classes you are inheriting from? Sometimes you cannot even fix this with overriding methods: You can easily construct a cut off ellipsoid from a regular ellipsoid, but then it stops being a quadric surface invalidating your nice class hierarchy. And you cannot change the class hierarchy because half of your codebase depends on it.
Patterns are like neat useful tricks. Like how to open a bottle with a hammer. Pretty nice to open your beer at the end of the day in a workshop. If you work in a bar and you constantly have to use tricks to use your hammer for your work you should probably rethink if a hammer is the right main tool for you.
No, it's not. Many places recommend restraint in use of inheritance (and in languages that support only single inheritance, there are sharp limits to what it can do to start with.)
That conclusion holds if your primary experience is Java: the Java class library is widely believed to have abused inheritance.
However other languages have avoided that trap. Apple's Cocoa frameworks in ObjC do use inheritance but also delegation, notifications, etc. Also Swift supports inheritance, but here we see Lattner describing inheritance as a "tool in our toolbox," not as the "go-to method for structuring everything."
> Inheritance is everything else but safe: you have to check if you broke the behavior of all methods and public fields you are inheriting.
Designing a class interface intended to be inherited is like any other API design exercise. Your API commits to invariants, and it's the client programmer's responsibility to follow them; if they do the class should not be broken.
If you find yourself checking "all methods and public fields," either the API is bad or you've misunderstood it.
Again, it's just one API design tool. Sometimes the alternative to inheritance is just an ad-hoc, bug-ridden re-implementation of inheritance.
What's "inheritance based OOP"? The kind of OOP that models everything using subclassing? Partly due to structural static typing so compatibility/polymorphism can only be achieved by having a common ancestor class?
Sure, but that's missing the point of OOP almost completely.
Anyway, subclassing is an extremely useful and by now somewhat underrated tool: it allows for unanticipated extension and programming-by-difference. Meaning you already have something that's close to but not quite what you need.
And they were both wrong, as millions of programmers use Java and C# and C++ just fine, and have created much more impressive software than what Dart or Golang programmers have. Plus, people used to the power of C++ would never switch to Golang (which is also what the Golang team observed: they mostly got people from Python/Ruby and that kind of services).
>Haskell and OCaml are a joy to program in, in part because they (mostly) eschew subtyping.
Sorry, but did you just said that "subtyping and parametric polymorphism (generics in Java) were deemed too hard for Google programmers to understand" (an argument based on complexity) and then went on to argue in favor of Haskell, which is notoriously difficult to grasp, and has so many foreign concepts that it makes Generics look like BASIC level concepts.
EDIT: my point was that subtyping is controversial, I assume the downvotes are for my own personal position.
Where I work we do have some business people successfully writing Haskell.
I've worked on very large codebases in many large organisations with C++, Java and Haskell. Haskell certainly wasn't the horror story.
How hard should they have tried? Should they have burnt the midnight oil?
This Java you talk about, is still in the top 1-3 languages by programmers, is it not?
And supposedly Haskell is easier (according to the parent comment) but at the same time needs people to try harder to get it than Java? It can't be both...
>I've worked on very large codebases in many large organisations with C++, Java and Haskell. Haskell certainly wasn't the horror story.
No, but it was the new novelty on greenfield staff. Easy to start as better. Java wasn't the horror story in 2000 either.
I'm disappointed that you appear to judge technology based on popularity. By this argument, JavaScript trumps Java.
> And supposedly Haskell is easier (according to the parent comment) but at the same time needs people to try harder to get it than Java? It can't be both...
I can assure you, having learned both, that understanding Java and all its idioms/patterns is at least as hard as learning Haskell, especially if one seeks to build concurrent software (where the intricacies of Java's complex memory model cannot be ignored).
Because of the immense amount of investment already made, likely these people give up when they realise they cannot make much use of it in Haskell, at least not at first.
> No, but it was the new novelty on greenfield staff.
You've made an incorrect assumption. The Haskell codebases I have worked on, in both cases, have been large and over a decade old.
Anyway, my original post was about the controversy of subtyping, not Haskell versus Java.
"It's simple once you've changed how you think about stuff" just hides the complexity in a prerequisite.
Not at all. You sound like you're looking for excuses not to learn something new!
No, because it's path dependency, not complexity.