Webcomponents are a good example for this practice
I was more focused on the domain scope of the program, not the adaptation with the "outside world". But I never explicitly said it was my focus, so my bad. When integrating with an existing system, built on top of some class hierarchy, I guess one does not have a choice but to create a subclass. I believe this subclass should be used as an adapter or "glue" between the world of HTML elements, and the world of pure logic specific to the domain (here, our domain is classifying animals for example).
I personally do not really understand the whole discussion "FP is better than OO" and vice versa.
I don't either, both of these paradigms can be used to build software that works as intended. That's why I've explicitly said in the previous article of this series that FP is, in no way, a replacement to OOP. That being said, I can see some benefits coming from the functional approach, specifically in terms of composability made easy thanks to small, reusable units. I think it's harder to correctly find the appropriate class hierarchy to avoid duplication while still being flexible in terms of "mix of data and behavior" with the inheritance approach.
We can apply a "functional style" also in OO.
I don't think this example is relevant, because we are comparing composition with inheritance here, not "functional style" code with non-functional. Composition can be achieved using OOP without relying on "FP style", for instance:
Here we have a mix of inheritance and composition. The inheritance part is used for the semantics (a Dog is an Animal) and the mechanics (any Animal has to eat). The composition part is used to mix behaviors, depending on the Animal we are "building".
I do believe there are good cases where inheritance is more suited (cf. Composition vs. Inheritance: How to Choose? on /thoughtworks), but in general I think it's easier to build software using composition over inheritance. And inheritance doesn't exist in FP, so we don't get to choose anyway :)
Reusing code is one of the strongest motivations to use inheritance. So I really do not understand the "drawbacks".
I agree with you about reusability, but I believe it requires more effort to find the appropriate class hierarchy (hence the "drawback"). When new requirements emerge, modifying the class hierarchy will require more effort than creating new blocks out of existing smaller blocks, by composing them.
Given your last class hierarchy with the Orca: let's say I want an animal that can walk and play with fishes, but can't swim (e.g. it plays with them in shallow waters). You can do that with inheritance, but you'll have to update the existing one to adapt it for this new requirement. For example:
+ abstract class WalkingAnimal extends Animal {
+ walk() {}
+ }
- class Dog extends Animal {
+ class Dog extends WalkingAnimal {
bark() {}
}abstract class PredatoryFish extends Animal {
- swim() {}
playWithFish() {}
}+ abstract class SwimmingPredatoryFish extends PredatoryFish {
+ swim() {}
+ }
+ abstract class WalkingPredatoryFish extends PredatoryFish {
+ walk() {} // code duplication? unless we use `walk = _walk.bind(this)` maybe?
+ }
- class Dolphin extends PredatoryFish {}
+ class Dolphin extends SwimmingPredatoryFish {}
+ class BearCub extends WalkingPredatoryFish {}
(I guess you can probably come up with a better class hierarchy that involves fewer changes and less code duplication ^^)
With composition there's more flexibility, and there are only additions, leading to fewer changes:
I fully agree that it is often more effort to use classes. It can be challenging to analyze your task and choose the right class hierarchy. So, there should always be a good reason to use classes.
But from my personal experience, the effort quickly pays back. If you made a bad decision in your design, it is easy to change the code without side effects. And in many cases, you do not need to care about implementation details. A well designed class should be usable as easy as a LEGO block.
Inside, classes are like separate programs. So, why not use the principles of FP to build classes? Maybe it is not necessary, but it´s possible and possibly helpful.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I was more focused on the domain scope of the program, not the adaptation with the "outside world". But I never explicitly said it was my focus, so my bad. When integrating with an existing system, built on top of some class hierarchy, I guess one does not have a choice but to create a subclass. I believe this subclass should be used as an adapter or "glue" between the world of HTML elements, and the world of pure logic specific to the domain (here, our domain is classifying animals for example).
I don't either, both of these paradigms can be used to build software that works as intended. That's why I've explicitly said in the previous article of this series that FP is, in no way, a replacement to OOP. That being said, I can see some benefits coming from the functional approach, specifically in terms of composability made easy thanks to small, reusable units. I think it's harder to correctly find the appropriate class hierarchy to avoid duplication while still being flexible in terms of "mix of data and behavior" with the inheritance approach.
I don't think this example is relevant, because we are comparing composition with inheritance here, not "functional style" code with non-functional. Composition can be achieved using OOP without relying on "FP style", for instance:
Here we have a mix of inheritance and composition. The inheritance part is used for the semantics (a
Dog
is anAnimal
) and the mechanics (anyAnimal
has toeat
). The composition part is used to mix behaviors, depending on theAnimal
we are "building".I do believe there are good cases where inheritance is more suited (cf. Composition vs. Inheritance: How to Choose? on /thoughtworks), but in general I think it's easier to build software using composition over inheritance. And inheritance doesn't exist in FP, so we don't get to choose anyway :)
I agree with you about reusability, but I believe it requires more effort to find the appropriate class hierarchy (hence the "drawback"). When new requirements emerge, modifying the class hierarchy will require more effort than creating new blocks out of existing smaller blocks, by composing them.
Given your last class hierarchy with the
Orca
: let's say I want an animal that can walk and play with fishes, but can't swim (e.g. it plays with them in shallow waters). You can do that with inheritance, but you'll have to update the existing one to adapt it for this new requirement. For example:(I guess you can probably come up with a better class hierarchy that involves fewer changes and less code duplication ^^)
With composition there's more flexibility, and there are only additions, leading to fewer changes:
Definitely! It's only a matter of code organization. No matter the paradigm, importing tens of functions in the same module is a bad smell anyway :D
I fully agree that it is often more effort to use classes. It can be challenging to analyze your task and choose the right class hierarchy. So, there should always be a good reason to use classes.
But from my personal experience, the effort quickly pays back. If you made a bad decision in your design, it is easy to change the code without side effects. And in many cases, you do not need to care about implementation details. A well designed class should be usable as easy as a LEGO block.
Inside, classes are like separate programs. So, why not use the principles of FP to build classes? Maybe it is not necessary, but it´s possible and possibly helpful.