3 ms·
If I get the idea, concepts are similar to Haskell's decade-old type classes, as an alternative to OOP classes and inheritance, which by now almost everybody ha
by jstimpfle 11y ago
If I get the idea, concepts are similar to Haskell's decade-old type classes, as an alternative to OOP classes and inheritance, which by now almost everybody has agreed are largely a bad idea from an architectural perspective. Did anyone see Edward Kmett's talk "Type classes vs the world" and wants to lose a few words on how they compare?
Regarding the problem you mentioned, I've often tried to break my problem domain in "abstract concepts" using templates, static assertions, code generation etc. I don't think I have a real word success story. Abstraction doesn't work out of course for business logic because generalizing over the mess which our world is is just incredibly hard, but also not for algorithms, because quite frankly, efficient implementation is the result from learning a thousand neat little tricks and applying them in the right situations. Abstraction remove these opportunities.
For example, recently I've seen a Java application with a parameterized container class. The parameters were abstract and thus the container had to use tons of nested Hashmaps to get from A to B. Had it admitted that the only sensible parameter was "int", everything could have been implemented using a few super-fast arrays.
Another problem is that abstraction actually grows cancerours dependencies across the code base. If we instead design clean data interfaces reusing basic data types and add a few lines of comments / constraints / consistency checks, this dependency hell just freezes down and we notice that abstraction wasn't the actual problem to begin with.
For the basic quick and dirty app, or script, of course it's extremely important to have generic STL containers and a std:: algorithm, or python dicts / set / iterators, and be done with it. Also in rare cases, abstractions like Monoid, Functor, Applicative, Traversable, Monad can come in handy when you can reuse a few lines of code from a generic library.
But to come back to your point, I think that's all largely explored territory and the point of diminishing returns has long been surpassed.
Thoughts? Counterexamples?
- EGreg 11y agoMy first thought is, why exactly do you think everyone concluded that OOP classes and inheritance is bad architecture?
- jstimpfle 11y agoIt's my impression -- I've heard it from so many programmers that I respect. The impression may be biased by my own frustrations dealing with bad abstractions (like: 90% of the classes I've seen out there are semantically broken, a.k.a not state machines). (To back that up, there is a python script of mine which I think is rather clean. It has basically a single class in it, which was needed because the API of cmd.Cmd relies on inheritance. I had to spend quite some time to circumvent that insane amount of brokenness. I've put in a few cynic comments out of frustration. If you're interested: https://github.com/jstimpfle/gitadmin/blob/08a2c0b7dd1a8950e3e9084a964ae3a248b29b39/gitadmin#L1303 https://github.com/jstimpfle/gitadmin/blob/08a2c0b7dd1a8950e... Good times.) Name the use cases where you think inheritance is a good fit.
- millstone 11y agoInheritance got a bad rap in part because object oriented analysis was done as an exercise in taxonomy (Employee is a Person is a Mammal is an Organism...), instead of identifying useful abstractions. A second problem is using inheritance when composition is obviously better. java.util.Stack is a lovely example of both sins in action. Where inheritance shines is in enabling close coupling across module boundaries. An example is event routing: how do you enable customization of how events flow through your app? UIKit handles this through inheritance. The base method gives you the default behavior, which you can override to customize. You can stop propagation by just not calling super, or redirect the event by calling the method somewhere else, etc. It's flexible. JavaScript handles this clumsily, by trying to anticipate all the customizations you might want to do and providing APIs for each of them (event.preventDefault, event.stopPropagation...) Despite all that, frameworks like React have to reimplement event dispatch, because the default behavior is too inflexible. Here inheritance is the glue that enabled close coupling between UIKit's default event dispatch algorithm and outside modifications to it.
- jstimpfle 11y agoYeah widget toolkits (if not done across maintenance boundaries) are really the one situation which is always described as a good fit for inheritance. However I don't think I like the idea of "close coupling across module boundaries". Sounds like an antithesis to sustainable architecture to me. Anyway I don't do UI...
- vmorgulis 11y agoA drawback of inheritance is strong coupling.